/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.func.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.je.common.base.DynaBean;
import com.je.common.base.JsonAssist;
import com.je.common.base.JsonBuilder;
import com.je.common.base.constants.table.TableType;
import com.je.common.base.constants.tree.NodeType;
import com.je.common.base.entity.extjs.DbModel;
import com.je.common.base.entity.extjs.Model;
import com.je.common.base.entity.func.FuncInfo;
import com.je.common.base.entity.func.FuncRelation;
import com.je.common.base.entity.func.FuncRelationField;
import com.je.common.base.exception.APIWarnException;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaRbacService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.service.rpc.CommonTableRpcService;
import com.je.common.base.service.rpc.SystemSettingRpcService;
import com.je.common.base.service.rpc.UpgradeModulePackageRpcService;
import com.je.common.base.table.service.PCDataService;
import com.je.common.base.util.*;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.cache.func.FuncConfigCache;
import com.je.meta.cache.func.FuncInfoCache;
import com.je.meta.cache.func.FuncStaticizeCache;
import com.je.meta.cache.table.DynaCache;
import com.je.meta.cache.table.TableCache;
import com.je.meta.model.func.FuncColumnTactic;
import com.je.meta.model.func.FuncColumnTacticInfo;
import com.je.meta.rpc.table.UpdateFuncTableInvokeRpcService;
import com.je.meta.service.common.MetaBeanService;
import com.je.meta.service.func.MetaCopyFuncService;
import com.je.meta.service.func.MetaFuncInfoService;
import com.je.meta.service.func.MetaFuncRelyonService;
import com.je.meta.service.func.entity.ButtonEntity;
import com.je.meta.service.func.syncConfig.SyncConfigManage;
import com.je.meta.service.func.syncConfig.SyncConfigService;
import com.je.meta.service.table.MetaResColumnService;
import com.je.meta.service.table.MetaTableColumnService;
import com.je.meta.service.table.MetaTableService;
import com.je.meta.util.SqlUtil;
import com.je.meta.util.enumUtil.EventInfoEnum;
import com.je.meta.util.enumUtil.FuncTypeEnum;
import com.je.meta.util.enumUtil.FuncinfoEnum;
import com.je.rbac.rpc.PermissionRpcService;
import com.je.servicecomb.RpcSchemaFactory;
import com.je.workflow.rpc.workflow.WorkFlowInfoRpcService;
import org.apache.commons.collections.ArrayStack;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Entity;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.je.servicecomb.JECloud.PRODUCT_CORE_META;

@Service
public class MetaFuncInfoServiceImpl implements MetaFuncInfoService {

    //需要剔除的系统字段
    public static final List<String> SYS_CODES = Lists.newArrayList("SY_AUDFLAG", "SY_CREATEORGID", "SY_CREATEORGNAME", "SY_CREATETIME", "SY_CREATEUSERID",
            "SY_CREATEUSERNAME", "SY_FLAG", "SY_FORMUPLOADFILES", "SY_MODIFYORGID", "SY_MODIFYORGNAME",
            "SY_MODIFYTIME", "SY_MODIFYUSERID", "SY_MODIFYUSERNAME", "SY_PDID", "SY_PIID", "SY_PYJZ", "SY_PYQC", "SY_STATUS");

    @Autowired
    private MetaService metaService;
    @Autowired
    private FuncInfoCache funcInfoCache;
    @Autowired
    private MetaBeanService metaBeanService;
    @Autowired
    private FuncConfigCache funcConfigCache;
    @Autowired
    private FuncStaticizeCache funcStaticizeCache;
    @Lazy
    @Autowired
    private CommonService commonService;
    @Lazy
    @Autowired
    private SystemSettingRpcService systemSettingRpcService;
    @Lazy
    @Autowired
    private MetaFuncRelyonService metaFuncRelyonService;
    @Lazy
    @Autowired
    private MetaResColumnService metaResColumnService;
    @Lazy
    @Autowired
    private MetaTableColumnService metaTableColumnService;
    @Lazy
    @Autowired
    private MetaTableService metaTableService;
    @Autowired
    private MetaRbacService metaRbacService;
    @Lazy
    @Autowired
    private MetaTableService tableService;
    @Autowired
    private WorkFlowInfoRpcService workFlowInfoRpcService;
    @Autowired
    private PermissionRpcService permissionRpcService;
    @Autowired
    private DynaCache dynaCache;
    @Autowired
    private TableCache tableCache;

    @Autowired
    private MetaCopyFuncService metaCopyFuncService;

    @Autowired
    @Qualifier("columnSyncConfigService")
    private SyncConfigService columnSyncConfigService;

    @Autowired
    @Qualifier("fieldSyncConfigService")
    private SyncConfigService fieldSyncConfigService;

    //EXTJS门面JSON辅助类
    public static JsonAssist jsonAssist;
    private static JsonBuilder jsonBuilder;

    static {
        jsonBuilder = JsonBuilder.getInstance();
        jsonAssist = JsonAssist.getInstance();
    }

    @Override
    @Transactional
    public void clearFuncAllStatize(String funcCodes) {
        if (Strings.isNullOrEmpty(funcCodes)) {
            return;
        }
        List<String> funcCodeList = Splitter.on(",").splitToList(funcCodes);
        String currentTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        if (Strings.isNullOrEmpty(currentTenantId)) {
            funcInfoCache.removeCache(funcCodeList);
        } else {
            funcInfoCache.removeCache(currentTenantId, funcCodeList);
        }
    }

    @Override
    public String translate(DynaBean dynaBean) {
        String sql = dynaBean.getStr("sql");
        List<DynaBean> columnList = metaService.select("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder().eq("RESOURCEFIELD_FUNCINFO_ID", dynaBean.getStr("funcId")));

        if (!columnList.isEmpty()) {
            String cnSql = getCnSql(sql, columnList);
            return cnSql;
        }
        return sql;
    }

    @Override
    @Transactional
    public DynaBean doSave(DynaBean dynaBean) {
        if (StringUtil.isEmpty(dynaBean.getStr("SY_PATH"))) {
            DynaBean parentInfo = metaService.selectOneByPk("JE_CORE_FUNCINFO", dynaBean.getStr("SY_PARENT"));
            dynaBean.setStr("SY_PATH", parentInfo.getStr("SY_PATH") + "/" + dynaBean.getStr("JE_CORE_FUNCINFO_ID"));
            dynaBean.setStr("SY_PARENTPATH", parentInfo.getStr("SY_PATH"));
            dynaBean.set("SY_LAYER", Integer.parseInt(parentInfo.getStr("SY_LAYER")) + 1);
        }
        dynaBean.setStr(dynaBean.getStr(BeanService.KEY_PK_CODE), dynaBean.getStr("JE_CORE_FUNCINFO_ID"));
        if (StringUtil.isEmpty(dynaBean.getStr("SY_NODETYPE"))) {
            dynaBean.set("SY_NODETYPE", NodeType.LEAF);
        }
        if ("FUNC".equals(dynaBean.getStr("FUNCINFO_NODEINFOTYPE")) || "FUNCFIELD".equals(dynaBean.getStr("FUNCINFO_NODEINFOTYPE"))) {
            buildDefaultFuncInfo(dynaBean);
        }

        dynaBean.set("SY_JECORE", "0");
        dynaBean.set("SY_JESYS", "1");
        commonService.buildModelCreateInfo(dynaBean);
        commonService.generateTreeOrderIndex(dynaBean);
        //字段标题宽度
        dynaBean.set("FUNCINFO_APPFORM_LABEL_WIDTH", "124");
        //字段标题位置
        dynaBean.set("FUNCINFO_APPFORM_LABEL_ALIGN", "left");
        //隐藏表单子功能导航
        dynaBean.set("FUNCINFO_APPFORM_DISABLE_CRUMB", "0");
        metaService.insert(dynaBean);
        if ("FUNC".equals(dynaBean.getStr("FUNCINFO_NODEINFOTYPE")) || "FUNCFIELD".equals(dynaBean.getStr("FUNCINFO_NODEINFOTYPE"))) {
            initFuncInfo(dynaBean);
            metaService.update(dynaBean);
            //批量调整功能列信息
            metaResColumnService.batchSortOutColumnInfoByFuncId(dynaBean.getStr("JE_CORE_FUNCINFO_ID"));
        }
        commonService.updateTreePanent4NodeType("JE_CORE_FUNCINFO", dynaBean.getStr("SY_PARENT"));
        return dynaBean;
    }


    @Override
    public List<Map<String, Object>> getJsEvent(DynaBean dynaBean) {
        String type = dynaBean.getStr("type");//功能：func；列：column；字段：field；按钮：button；Action列:action
        String id = dynaBean.getStr("id");
        String tableCode = EventInfoEnum.valueOf(type).getTableCode();
        String whereSql = EventInfoEnum.valueOf(type).getWhereSql();
        if (!StringUtil.isEmpty(id) && !"func".equals(type)) {
            DynaBean db = new DynaBean(tableCode, true);
            whereSql += " AND " + db.getPkCode() + "=" + "'" + id + "'";
        }
        String queryField = EventInfoEnum.valueOf(type).getQueryField();
        String foreignKey = EventInfoEnum.valueOf(type).getForeignKey();
        List<Map<String, Object>> list = metaService.selectSql("select " + queryField + " from " + tableCode + " where " + foreignKey + "=" + "'" + dynaBean.getStr("funcId") + "'" + whereSql);
        return list;
    }

    private String getCnSql(String sqlStr, List<DynaBean> columnList) {
        /**
         * 将多个空格变为一个空格
         */
        sqlStr = sqlStr.replaceAll("\\s+", " ");
        String cnStr = "";
        String regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？\" \",}]";
        Pattern p = Pattern.compile(regEx);
        Matcher m1 = p.matcher(sqlStr);
        List<String> strList = new ArrayList<>();
        if (m1.find()) {
            CharSequence cs = sqlStr;
            int s = 0;
            int e = 0;
            StringBuilder sb = new StringBuilder(sqlStr);
            for (int i = 0; i < cs.length(); i++) {
                String temp = String.valueOf(cs.charAt(i));
                Matcher m2 = p.matcher(temp);
                if (m2.find()) {
                    e = i;
                    strList.add(sqlStr.substring(s, e));//截特殊字符之前的
                    s = e;
                    e = i + 1;
                    strList.add(sqlStr.substring(s, e));//截当前特殊字符
                    s = e;
                }
            }
            String lastStr = sqlStr.substring(e, sqlStr.length()).replace(" ", "");
            strList.add(lastStr);

            for (int i = 0; i < strList.size(); i++) {
                String itemstr = strList.get(i);
                if (StringUtil.isNotEmpty(itemstr)) {
                    for (DynaBean db : columnList) {
                        String colimnCode = db.getStr("RESOURCEFIELD_CODE");
                        String type = db.getStr("RESOURCEFIELD_XTYPE");
                        /**
                         * 运用到了字典，值取字典里的
                         */
                        if (colimnCode.equalsIgnoreCase(itemstr)) {
                            itemstr = db.getStr("RESOURCEFIELD_NAME");
                            if ("cbbfield".equals(type)) {
                                String configinfo = db.getStr("RESOURCEFIELD_CONFIGINFO");
                                String[] arr = configinfo.split(ArrayUtils.SPLIT);
                                List<Map<String, Object>> itemMap = metaService.selectSql("select DICTIONARYITEM_ITEMNAME,DICTIONARYITEM_ITEMCODE from JE_CORE_DICTIONARYITEM where  SY_NODETYPE='LEAF' and DICTIONARYITEM_DICTIONARY_ID in (select JE_CORE_DICTIONARY_ID from JE_CORE_DICTIONARY WHERE DICTIONARY_DDCODE= {0} and (SY_STATUS = '' or SY_STATUS = '1' or SY_STATUS is NULL))", arr[0]);
                                if (itemMap != null && itemMap.size() > 0) {
                                    boolean breakFlag = false;
                                    for (int j = i; j < strList.size() && !breakFlag; j++) {
                                        String dicV = strList.get(j);
                                        for (Map<String, Object> item : itemMap) {
                                            String code = item.get("DICTIONARYITEM_ITEMCODE").toString();
                                            if (dicV.equals(code)) {
                                                //itemstr = item.get("DICTIONARYITEM_ITEMNAME").toString();
                                                strList.set(j, item.get("DICTIONARYITEM_ITEMNAME").toString());
                                                breakFlag = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        }

                    }
                }
                cnStr += itemstr;
            }
        }
        return cnStr;
    }

    @Override
    @Transactional
    public void implButton(DynaBean funInfo, String funId) {
        List<DynaBean> buttonList = metaService.select("JE_CORE_RESOURCEBUTTON", ConditionsWrapper.builder().eq("RESOURCEBUTTON_FUNCINFO_ID", funId));
        String editDisabled = "0";
        String tableCode = funInfo.getStr("FUNCINFO_TABLENAME");
        if (StringUtil.isNotEmpty(tableCode)) {
            DynaBean table = metaBeanService.getResourceTable(tableCode);
            if (TableType.VIEWTABLE.equals(table.getStr("RESOURCETABLE_TYPE"))) {
                editDisabled = "1";
            }
        }

        if (buttonList != null && !buttonList.isEmpty()) {
            return;
        }

        //是产品新增还是项目新增
        String sysMode = null;
        //列表按钮
        //列表添加
        DynaBean add = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        add.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        add.set("RESOURCEBUTTON_CODE", "gridInsertBtn");
        //列表按钮
        add.set("RESOURCEBUTTON_ISFORM", "0");
        add.set("RESOURCEBUTTON_NAME", "创建");
        add.set("RESOURCEBUTTON_NAME_EN", "Create");
        //可用   true
        add.set("RESOURCEBUTTON_DISABLED", editDisabled);
        add.set("RESOURCEBUTTON_HIDDEN", "0");
        add.set("RESOURCEBUTTON_TYPE", "GRID");
        add.set("RESOURCEBUTTON_BIGICONCLS", "list_add_32");
        //使用范围
        add.set("RESOURCEBUTTON_USE_SCOPE", "ALL");
        //绑定表单验证   false
        add.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式
        add.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-new-form");
        add.setStr("RESOURCEBUTTON_ICON", "jeicon jeicon-plus");
        add.set("RESOURCEBUTTON_FONTICONCLS", "fe icon-plus");
        add.set("RESOURCEBUTTON_CLS", "JEPLUS_B_L10");
        add.set("SY_ORDERINDEX", 1);
        add.set("RESOURCEBUTTON_SYSMODE", sysMode);
        add.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        commonService.buildModelCreateInfo(add);
        metaService.insert(add);
        //列表编辑
        DynaBean edit = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        edit.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        edit.set("RESOURCEBUTTON_CODE", "gridEditBtn");
        edit.set("RESOURCEBUTTON_NAME", "编辑");
        edit.set("RESOURCEBUTTON_NAME_EN", "Edit");
        //可用   true
        edit.set("RESOURCEBUTTON_DISABLED", "0");
        //列表按钮
        edit.set("RESOURCEBUTTON_ISFORM", "0");
        edit.set("RESOURCEBUTTON_HIDDEN", "0");
        edit.set("RESOURCEBUTTON_TYPE", "GRID");
        //使用范围
        edit.set("RESOURCEBUTTON_USE_SCOPE", "ALL");
        edit.set("RESOURCEBUTTON_BIGICONCLS", "list_edit_32");
        //绑定表单验证   false
        edit.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式
        edit.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-form-editing");
        edit.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-edit");
        edit.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C07");
        edit.set("SY_ORDERINDEX", 2);
        edit.set("RESOURCEBUTTON_SYSMODE", sysMode);
        edit.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        edit.setStr("RESOURCEBUTTON_POSITION", "MULTI");
        edit.setStr("RESOURCEBUTTON_BGCOLOR", "#FFFFFF");
        edit.setStr("RESOURCEBUTTON_FONTCOLOR", "#3F3F3F");
        edit.setStr("RESOURCEBUTTON_BORDERCOLOR", "#D9D9D9");
        edit.setStr("RESOURCEBUTTON_ICON", "fal fa-edit");
        commonService.buildModelCreateInfo(edit);
        metaService.insert(edit);
        //列表保存
        DynaBean gridSave = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        gridSave.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        gridSave.set("RESOURCEBUTTON_CODE", "gridUpdateBtn");
        gridSave.set("RESOURCEBUTTON_NAME", "保存");
        gridSave.set("RESOURCEBUTTON_NAME_EN", "Save");
        //可用   true
        gridSave.set("RESOURCEBUTTON_DISABLED", editDisabled);
        //列表按钮
        gridSave.set("RESOURCEBUTTON_ISFORM", "0");
        gridSave.set("RESOURCEBUTTON_HIDDEN", "0");
        gridSave.set("RESOURCEBUTTON_TYPE", "GRID");
        //使用范围
        gridSave.set("RESOURCEBUTTON_USE_SCOPE", "PC");
        gridSave.set("RESOURCEBUTTON_BIGICONCLS", "list_save_32");
        //绑定表单验证   false
        gridSave.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式
        gridSave.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-form-save");
        gridSave.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-save");
        gridSave.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C07");
        gridSave.set("RESOURCEBUTTON_POSITION", "BAR,MULTI");
        gridSave.set("RESOURCEBUTTON_DISABLED", "1");
        gridSave.set("SY_ORDERINDEX", 3);
        gridSave.set("RESOURCEBUTTON_SYSMODE", sysMode);
        gridSave.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        gridSave.setStr("RESOURCEBUTTON_BGCOLOR", "#FFFFFF");
        gridSave.setStr("RESOURCEBUTTON_FONTCOLOR", "#3F3F3F");
        gridSave.setStr("RESOURCEBUTTON_BORDERCOLOR", "#D9D9D9");
        gridSave.setStr("RESOURCEBUTTON_ICON", "fal fa-save");
        commonService.buildModelCreateInfo(gridSave);
        metaService.insert(gridSave);
        //列表删除
        DynaBean delete = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        delete.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        delete.set("RESOURCEBUTTON_CODE", "gridRemoveBtn");
        delete.set("RESOURCEBUTTON_NAME", "删除");
        delete.set("RESOURCEBUTTON_NAME_EN", "Delete");
        //可用   true
        delete.set("RESOURCEBUTTON_DISABLED", editDisabled);
        //列表按钮
        delete.set("RESOURCEBUTTON_ISFORM", "0");
        delete.set("RESOURCEBUTTON_HIDDEN", "0");
        delete.set("RESOURCEBUTTON_TYPE", "GRID");
        //使用范围
        delete.set("RESOURCEBUTTON_USE_SCOPE", "ALL");
        delete.set("RESOURCEBUTTON_BIGICONCLS", "list_delete_32");
        //绑定表单验证   false
        delete.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式fa
        delete.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-delete-form");
        delete.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-remove");
        delete.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C07");
        delete.set("SY_ORDERINDEX", 4);
        delete.set("RESOURCEBUTTON_SYSMODE", sysMode);
        delete.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        delete.set("RESOURCEBUTTON_POSITION", "MULTI");
        delete.setStr("RESOURCEBUTTON_BGCOLOR", "#FFFFFF");
        delete.setStr("RESOURCEBUTTON_FONTCOLOR", "#3F3F3F");
        delete.setStr("RESOURCEBUTTON_BORDERCOLOR", "#D9D9D9");
        delete.setStr("RESOURCEBUTTON_ICON", "jeicon jeicon-times");
        commonService.buildModelCreateInfo(delete);
        metaService.insert(delete);
        //列表禁用
        /*DynaBean disabled = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        disabled.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        disabled.set("RESOURCEBUTTON_CODE", "gridDisabledBtn");
        disabled.set("RESOURCEBUTTON_NAME", "禁用");
        disabled.set("RESOURCEBUTTON_NAME_EN", "Disable");
        //可用   true
        disabled.set("RESOURCEBUTTON_DISABLED", "1");
        //列表按钮
        disabled.set("RESOURCEBUTTON_ISFORM", "0");
        disabled.set("RESOURCEBUTTON_HIDDEN", "0");
        disabled.set("RESOURCEBUTTON_TYPE", "GRID");
        disabled.set("RESOURCEBUTTON_BIGICONCLS", "list_delete_32");
        //绑定表单验证   false
        disabled.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式
        disabled.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-delete-form");
        disabled.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-remove");
        disabled.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C07");
        disabled.set("SY_ORDERINDEX", 5);
        disabled.set("RESOURCEBUTTON_SYSMODE", sysMode);
        disabled.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        disabled.set("RESOURCEBUTTON_POSITION", "MULTI");
        disabled.setStr("RESOURCEBUTTON_BGCOLOR","#FFFFFF");
        disabled.setStr("RESOURCEBUTTON_FONTCOLOR","#3F3F3F");
        disabled.setStr("RESOURCEBUTTON_BORDERCOLOR","#D9D9D9");
        disabled.setStr("RESOURCEBUTTON_ICON","fal fa-ban");
        commonService.buildModelCreateInfo(disabled);
        metaService.insert(disabled);*/
        //导出
        DynaBean export = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        export.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        export.set("RESOURCEBUTTON_CODE", "gridExportXLSBtn");
        export.set("RESOURCEBUTTON_NAME", "导出");
        export.set("RESOURCEBUTTON_NAME_EN", "Export");
        //可用   true
        export.set("RESOURCEBUTTON_DISABLED", "0");
        //列表按钮
        export.set("RESOURCEBUTTON_ISFORM", "0");
        export.set("RESOURCEBUTTON_HIDDEN", "0");
        export.set("RESOURCEBUTTON_TYPE", "GRID");
        //使用范围
        export.set("RESOURCEBUTTON_USE_SCOPE", "PC");
        export.set("RESOURCEBUTTON_BIGICONCLS", "lies_to_excel");
        //绑定表单验证   false
        export.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式
        export.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-print");
        export.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-file-excel-o");
        export.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C07");
        export.set("SY_ORDERINDEX", 6);
        export.set("RESOURCEBUTTON_SYSMODE", sysMode);
        export.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        export.set("RESOURCEBUTTON_POSITION", "BAR,MULTI");
        export.setStr("RESOURCEBUTTON_BGCOLOR", "#FFFFFF");
        export.setStr("RESOURCEBUTTON_FONTCOLOR", "#3F3F3F");
        export.setStr("RESOURCEBUTTON_BORDERCOLOR", "#D9D9D9");
        export.setStr("RESOURCEBUTTON_ICON", "fal fa-file-export");
        export.setStr("RESOURCEBUTTON_NOREADONLY", "1");
        commonService.buildModelCreateInfo(export);
        metaService.insert(export);
        //表单按钮
        //表单保存
        DynaBean formSave = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        formSave.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        formSave.set("RESOURCEBUTTON_CODE", "formSaveBtn");
        formSave.set("RESOURCEBUTTON_NAME", "保存");
        formSave.set("RESOURCEBUTTON_NAME_EN", "Save");
        //可用   true
        formSave.set("RESOURCEBUTTON_DISABLED", editDisabled);
        //列表按钮
        formSave.set("RESOURCEBUTTON_ISFORM", "1");
        formSave.set("RESOURCEBUTTON_HIDDEN", "0");
        formSave.set("RESOURCEBUTTON_TYPE", "FORM");
        //使用范围
        formSave.set("RESOURCEBUTTON_USE_SCOPE", "ALL");
        formSave.set("RESOURCEBUTTON_BIGICONCLS", "list_save_32_3");
        //绑定表单验证   false
        formSave.set("RESOURCEBUTTON_FORMBIND", "1");
        //按钮样式
        formSave.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-save");
        formSave.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-save");
        formSave.set("RESOURCEBUTTON_CLS", "JEPLUS_B_L10");
        formSave.set("SY_ORDERINDEX", 7);
        formSave.set("RESOURCEBUTTON_SYSMODE", sysMode);
        formSave.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        formSave.setStr("RESOURCEBUTTON_ICON", "fal fa-save");
        commonService.buildModelCreateInfo(formSave);
        metaService.insert(formSave);
        //保存新建
        /*DynaBean formNew = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        formNew.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        formNew.set("RESOURCEBUTTON_CODE", "formNewBtn");
        formNew.set("RESOURCEBUTTON_NAME", "创建");
        formNew.set("RESOURCEBUTTON_NAME_EN", "Create");
        //可用   true
        formNew.set("RESOURCEBUTTON_DISABLED", editDisabled);
        //列表按钮
        formNew.set("RESOURCEBUTTON_ISFORM", "1");
        formNew.set("RESOURCEBUTTON_HIDDEN", "0");
        formNew.set("RESOURCEBUTTON_TYPE", "FORM");
        formNew.set("RESOURCEBUTTON_BIGICONCLS", "fomr_save_new_32");
        //绑定表单验证   false
        formNew.set("RESOURCEBUTTON_FORMBIND", "1");
        //按钮样式
        formNew.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-new-preservation");
        formNew.set("RESOURCEBUTTON_FONTICONCLS", "fe icon-plus");
        formNew.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C07");
        formNew.set("RESOURCEBUTTON_DISABLED", "1");
        formNew.set("SY_ORDERINDEX", 8);
        formNew.set("RESOURCEBUTTON_SYSMODE", sysMode);
        formNew.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        formNew.setStr("RESOURCEBUTTON_BGCOLOR","#FFFFFF");
        formNew.setStr("RESOURCEBUTTON_FONTCOLOR","#3F3F3F");
        formNew.setStr("RESOURCEBUTTON_BORDERCOLOR","#D9D9D9");
        formNew.setStr("RESOURCEBUTTON_ICON","jeicon jeicon-plus");
        commonService.buildModelCreateInfo(formNew);
        metaService.insert(formNew);
        //保存复制
        DynaBean formCopy = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        formCopy.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        formCopy.set("RESOURCEBUTTON_CODE", "formCopyBtn");
        formCopy.set("RESOURCEBUTTON_NAME", "复制");
        formCopy.set("RESOURCEBUTTON_NAME_EN", "Copy");
        //可用   true
        formCopy.set("RESOURCEBUTTON_DISABLED", editDisabled);
        //列表按钮
        formCopy.set("RESOURCEBUTTON_ISFORM", "1");
        formCopy.set("RESOURCEBUTTON_HIDDEN", "0");
        formCopy.set("RESOURCEBUTTON_TYPE", "FORM");
        formCopy.set("RESOURCEBUTTON_DISABLED", "1");
        formCopy.set("RESOURCEBUTTON_BIGICONCLS", "form_save_copy_32");
        //绑定表单验证   false
        formCopy.set("RESOURCEBUTTON_FORMBIND", "1");
        //按钮样式
        formCopy.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-save-copy");
        formCopy.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-clone");
        formCopy.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C07");
        formCopy.set("SY_ORDERINDEX", 9);
        formCopy.set("RESOURCEBUTTON_SYSMODE", sysMode);
        formCopy.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        formCopy.setStr("RESOURCEBUTTON_BGCOLOR","#FFFFFF");
        formCopy.setStr("RESOURCEBUTTON_FONTCOLOR","#3F3F3F");
        formCopy.setStr("RESOURCEBUTTON_BORDERCOLOR","#D9D9D9");
        formCopy.setStr("RESOURCEBUTTON_ICON","fal fa-copy");
        commonService.buildModelCreateInfo(formCopy);
        metaService.insert(formCopy);*/
        //返回
        DynaBean formBack = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        formBack.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        formBack.set("RESOURCEBUTTON_CODE", "formBackBtn");
        formBack.set("RESOURCEBUTTON_NAME", "返回");
        formBack.set("RESOURCEBUTTON_NAME_EN", "Back");
        //可用   true
        formBack.set("RESOURCEBUTTON_DISABLED", "0");
        //列表按钮
        formBack.set("RESOURCEBUTTON_ISFORM", "1");
        formBack.set("RESOURCEBUTTON_HIDDEN", "0");
        formBack.set("RESOURCEBUTTON_TYPE", "FORM");
        //使用范围
        formBack.set("RESOURCEBUTTON_USE_SCOPE", "PC");
        formBack.set("RESOURCEBUTTON_BIGICONCLS", "form_back_32");
        //绑定表单验证   false
        formBack.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式
        formBack.set("RESOURCEBUTTON_ICONCLS", "jeicon jeicon-rejected");
        formBack.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-mail-reply");
        formBack.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C07");
        formBack.set("SY_ORDERINDEX", 10);
        formBack.set("RESOURCEBUTTON_SYSMODE", sysMode);
        formBack.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        formBack.setStr("RESOURCEBUTTON_BGCOLOR", "#FFFFFF");
        formBack.setStr("RESOURCEBUTTON_FONTCOLOR", "#3F3F3F");
        formBack.setStr("RESOURCEBUTTON_BORDERCOLOR", "#D9D9D9");
        formBack.setStr("RESOURCEBUTTON_ICON", "fal fa-arrow-left");
        commonService.buildModelCreateInfo(formBack);
        metaService.insert(formBack);
        //ACTION列
        DynaBean actionUpdate = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        actionUpdate.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        actionUpdate.set("RESOURCEBUTTON_CODE", "actionUpdate");
        actionUpdate.set("RESOURCEBUTTON_NAME", "保存");
        actionUpdate.set("RESOURCEBUTTON_NAME_EN", "Save");
        //可用   true
        actionUpdate.set("RESOURCEBUTTON_DISABLED", "0");
        //列表按钮
        actionUpdate.set("RESOURCEBUTTON_ISFORM", "0");
        actionUpdate.set("RESOURCEBUTTON_HIDDEN", "0");
        actionUpdate.set("RESOURCEBUTTON_TYPE", "ACTION");
        //使用范围
        actionUpdate.set("RESOURCEBUTTON_USE_SCOPE", "PC");
        //jeicon jeicon-save-storage
        actionUpdate.set("RESOURCEBUTTON_BIGICONCLS", "");
        //绑定表单验证   false
        actionUpdate.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式jeicon jeicon-save-storage
        actionUpdate.set("RESOURCEBUTTON_ICONCLS", "");
        actionUpdate.set("RESOURCEBUTTON_FONTICONCLS", "fe icon-ok-2");
        actionUpdate.set("RESOURCEBUTTON_FONTICONCOLOR", "#02632f");
        actionUpdate.set("SY_ORDERINDEX", 11);
        actionUpdate.set("RESOURCEBUTTON_SYSMODE", sysMode);
        actionUpdate.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        actionUpdate.set("RESOURCEBUTTON_DISABLED", "1");
        //actionUpdate.set("RESOURCEBUTTON_JSLISTENER", URLDecoder.decode("%7B%22code%22%3A%22handler%22%2C%22name%22%3A%22%5Cu5355%5Cu51fb%22%2C%22func%22%3A%22%2F**%5Cn%20*%20action%5Cu6309%5Cu94ae%5Cu5355%5Cu51fb%5Cu4e8b%5Cu4ef6%5Cn%20*%20%40param%20%7B%7D%20grid%20%5Cu5217%5Cu8868%5Cn%20*%20%40param%20%7B%7D%20model%20%5Cu5f53%5Cu524d%5Cu884c%5Cu7684%5Cu6570%5Cu636e%5Cn%20*%20%40param%20%7B%7D%20rowIndex%20%5Cu884c%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%20%40param%20%7B%7D%20colIndex%20%5Cu5217%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%2F%5Cnfunction(grid%2Cmodel%2CrowIndex%2CcolIndex)%7B%5Cn%5Cn%7D%22%2C%22fire%22%3A%221%22%2C%22newfunc%22%3A%22%2F**%5Cn%20*%20action%5Cu6309%5Cu94ae%5Cu5355%5Cu51fb%5Cu4e8b%5Cu4ef6%5Cn%20*%20%40param%20%7B%7D%20grid%20%5Cu5217%5Cu8868%5Cn%20*%20%40param%20%7B%7D%20model%20%5Cu5f53%5Cu524d%5Cu884c%5Cu7684%5Cu6570%5Cu636e%5Cn%20*%20%40param%20%7B%7D%20rowIndex%20%5Cu884c%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%20%40param%20%7B%7D%20colIndex%20%5Cu5217%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%2F%5Cnfunction(grid%2Cmodel%2CrowIndex%2CcolIndex)%7B%5Cn%20%20JE.Action.doUpdateList(grid%2Cgrid.funcData.info%2C%5Bmodel%5D)%3B%5Cn%7D%22%7D"));
        commonService.buildModelCreateInfo(actionUpdate);
        metaService.insert(actionUpdate);
        DynaBean actionEdit = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        actionEdit.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        actionEdit.set("RESOURCEBUTTON_CODE", "actionEdit");
        actionEdit.set("RESOURCEBUTTON_NAME", "编辑");
        actionEdit.set("RESOURCEBUTTON_NAME_EN", "Edit");
        //可用   true
        actionEdit.set("RESOURCEBUTTON_DISABLED", "0");
        //列表按钮
        actionEdit.set("RESOURCEBUTTON_ISFORM", "0");
        actionEdit.set("RESOURCEBUTTON_HIDDEN", "0");
        actionEdit.set("RESOURCEBUTTON_TYPE", "ACTION");
        //使用范围
        actionEdit.set("RESOURCEBUTTON_USE_SCOPE", "PC");
        //jeicon jeicon-save-storage
        actionEdit.set("RESOURCEBUTTON_BIGICONCLS", "");
        //绑定表单验证   false
        actionEdit.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式jeicon jeicon-save-storage
        actionEdit.set("RESOURCEBUTTON_ICONCLS", "");
        actionEdit.set("RESOURCEBUTTON_FONTICONCLS", "fe icon-brush");
        actionEdit.set("RESOURCEBUTTON_FONTICONCOLOR", "#02632f");
        actionEdit.set("SY_ORDERINDEX", 12);
        actionEdit.set("RESOURCEBUTTON_SYSMODE", sysMode);
        actionEdit.set("RESOURCEBUTTON_DISABLED", "1");
        //actionEdit.set("RESOURCEBUTTON_JSLISTENER", URLDecoder.decode("%7B%22code%22%3A%22handler%22%2C%22name%22%3A%22%5Cu5355%5Cu51fb%22%2C%22func%22%3A%22%2F**%5Cn%20*%20action%5Cu6309%5Cu94ae%5Cu5355%5Cu51fb%5Cu4e8b%5Cu4ef6%5Cn%20*%20%40param%20%7B%7D%20grid%20%5Cu5217%5Cu8868%5Cn%20*%20%40param%20%7B%7D%20model%20%5Cu5f53%5Cu524d%5Cu884c%5Cu7684%5Cu6570%5Cu636e%5Cn%20*%20%40param%20%7B%7D%20rowIndex%20%5Cu884c%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%20%40param%20%7B%7D%20colIndex%20%5Cu5217%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%2F%5Cnfunction(grid%2Cmodel%2CrowIndex%2CcolIndex)%7B%5Cn%5Cn%7D%22%2C%22fire%22%3A%221%22%2C%22newfunc%22%3A%22%2F**%5Cn%20*%20action%5Cu6309%5Cu94ae%5Cu5355%5Cu51fb%5Cu4e8b%5Cu4ef6%5Cn%20*%20%40param%20%7B%7D%20grid%20%5Cu5217%5Cu8868%5Cn%20*%20%40param%20%7B%7D%20model%20%5Cu5f53%5Cu524d%5Cu884c%5Cu7684%5Cu6570%5Cu636e%5Cn%20*%20%40param%20%7B%7D%20rowIndex%20%5Cu884c%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%20%40param%20%7B%7D%20colIndex%20%5Cu5217%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%2F%5Cnfunction(grid%2Cmodel%2CrowIndex%2CcolIndex)%7B%5Cn%20%20grid.getSelectionModel().select(model)%3B%5Cn%20%20JE.Action.doEdit(grid%2Cmodel%2Cgrid.funcData.info)%3B%5Cn%7D%22%7D"));
        actionEdit.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        commonService.buildModelCreateInfo(actionEdit);
        metaService.insert(actionEdit);
        DynaBean actionRemove = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        actionRemove.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        actionRemove.set("RESOURCEBUTTON_CODE", "actionRemove");
        actionRemove.set("RESOURCEBUTTON_NAME", "删除");
        actionRemove.set("RESOURCEBUTTON_NAME_EN", "Delete");
        //可用   true
        actionRemove.set("RESOURCEBUTTON_DISABLED", "0");
        //列表按钮
        actionRemove.set("RESOURCEBUTTON_ISFORM", "0");
        actionRemove.set("RESOURCEBUTTON_HIDDEN", "0");
        actionRemove.set("RESOURCEBUTTON_TYPE", "ACTION");
        //使用范围
        actionRemove.set("RESOURCEBUTTON_USE_SCOPE", "PC");
        //jeicon jeicon-cut-back
        actionRemove.set("RESOURCEBUTTON_BIGICONCLS", "");
        //绑定表单验证   false
        actionRemove.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式jeicon jeicon-cut-back
        actionRemove.set("RESOURCEBUTTON_ICONCLS", "");
        actionRemove.set("RESOURCEBUTTON_FONTICONCLS", "fe icon-cancel-5");
        actionRemove.set("RESOURCEBUTTON_FONTICONCOLOR", "#02632f");
        actionRemove.set("SY_ORDERINDEX", 13);
        actionRemove.set("RESOURCEBUTTON_SYSMODE", sysMode);
        actionRemove.set("RESOURCEBUTTON_DISABLED", "1");
        // actionRemove.set("RESOURCEBUTTON_JSLISTENER", URLDecoder.decode("%7B%22code%22%3A%22handler%22%2C%22name%22%3A%22%5Cu5355%5Cu51fb%22%2C%22func%22%3A%22%2F**%5Cn%20*%20action%5Cu6309%5Cu94ae%5Cu5355%5Cu51fb%5Cu4e8b%5Cu4ef6%5Cn%20*%20%40param%20%7B%7D%20grid%20%5Cu5217%5Cu8868%5Cn%20*%20%40param%20%7B%7D%20model%20%5Cu5f53%5Cu524d%5Cu884c%5Cu7684%5Cu6570%5Cu636e%5Cn%20*%20%40param%20%7B%7D%20rowIndex%20%5Cu884c%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%20%40param%20%7B%7D%20colIndex%20%5Cu5217%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%2F%5Cnfunction(grid%2Cmodel%2CrowIndex%2CcolIndex)%7B%5Cn%5Cn%7D%22%2C%22fire%22%3A%221%22%2C%22newfunc%22%3A%22%2F**%5Cn%20*%20action%5Cu6309%5Cu94ae%5Cu5355%5Cu51fb%5Cu4e8b%5Cu4ef6%5Cn%20*%20%40param%20%7B%7D%20grid%20%5Cu5217%5Cu8868%5Cn%20*%20%40param%20%7B%7D%20model%20%5Cu5f53%5Cu524d%5Cu884c%5Cu7684%5Cu6570%5Cu636e%5Cn%20*%20%40param%20%7B%7D%20rowIndex%20%5Cu884c%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%20%40param%20%7B%7D%20colIndex%20%5Cu5217%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%2F%5Cnfunction(grid%2Cmodel%2CrowIndex%2CcolIndex)%7B%5Cn%5Ctgrid.getSelectionModel().select(model)%3B%5Cn%5CtJE.Action.doRemove(grid%2Cgrid.funcData.info%2C%5Bmodel%5D)%3B%5Cn%7D%22%7D"));
        actionRemove.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        commonService.buildModelCreateInfo(actionRemove);
        metaService.insert(actionRemove);
        DynaBean actionAdd = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
        actionAdd.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
        actionAdd.set("RESOURCEBUTTON_CODE", "actionAdd");
        actionAdd.set("RESOURCEBUTTON_NAME", "添加");
        actionAdd.set("RESOURCEBUTTON_NAME_EN", "Add");
        //可用   true
        actionAdd.set("RESOURCEBUTTON_DISABLED", "0");
        //列表按钮
        actionAdd.set("RESOURCEBUTTON_ISFORM", "0");
        actionAdd.set("RESOURCEBUTTON_HIDDEN", "0");
        actionAdd.set("RESOURCEBUTTON_TYPE", "ACTION");
        //使用范围
        actionAdd.set("RESOURCEBUTTON_USE_SCOPE", "PC");
        //jeicon jeicon-add
        actionAdd.set("RESOURCEBUTTON_BIGICONCLS", "");
        //绑定表单验证   false
        actionAdd.set("RESOURCEBUTTON_FORMBIND", "0");
        //按钮样式jeicon jeicon-add
        actionAdd.set("RESOURCEBUTTON_ICONCLS", "");
        actionAdd.set("RESOURCEBUTTON_FONTICONCLS", "fe icon-plus-squared");
        actionAdd.set("RESOURCEBUTTON_FONTICONCOLOR", "#02632f");
        actionAdd.set("SY_ORDERINDEX", 14);
        actionAdd.set("RESOURCEBUTTON_SYSMODE", sysMode);
        actionAdd.set("RESOURCEBUTTON_DISABLED", "1");
        //actionAdd.set("RESOURCEBUTTON_JSLISTENER", URLDecoder.decode("%7B%22code%22%3A%22handler%22%2C%22name%22%3A%22%5Cu5355%5Cu51fb%22%2C%22func%22%3A%22%2F**%5Cn%20*%20action%5Cu6309%5Cu94ae%5Cu5355%5Cu51fb%5Cu4e8b%5Cu4ef6%5Cn%20*%20%40param%20%7B%7D%20grid%20%5Cu5217%5Cu8868%5Cn%20*%20%40param%20%7B%7D%20model%20%5Cu5f53%5Cu524d%5Cu884c%5Cu7684%5Cu6570%5Cu636e%5Cn%20*%20%40param%20%7B%7D%20rowIndex%20%5Cu884c%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%20%40param%20%7B%7D%20colIndex%20%5Cu5217%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%2F%5Cnfunction(grid%2Cmodel%2CrowIndex%2CcolIndex)%7B%5Cn%5Cn%7D%22%2C%22fire%22%3A%221%22%2C%22newfunc%22%3A%22%2F**%5Cn%20*%20action%5Cu6309%5Cu94ae%5Cu5355%5Cu51fb%5Cu4e8b%5Cu4ef6%5Cn%20*%20%40param%20%7B%7D%20grid%20%5Cu5217%5Cu8868%5Cn%20*%20%40param%20%7B%7D%20model%20%5Cu5f53%5Cu524d%5Cu884c%5Cu7684%5Cu6570%5Cu636e%5Cn%20*%20%40param%20%7B%7D%20rowIndex%20%5Cu884c%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%20%40param%20%7B%7D%20colIndex%20%5Cu5217%5Cu7684%5Cu7d22%5Cu5f15%5Cn%20*%2F%5Cnfunction(grid%2Cmodel%2CrowIndex%2CcolIndex)%7B%5Cn%5CtJE.Action.doAdd(grid%2Cgrid.funcData.info)%3B%20%5Cn%7D%22%7D"));
        actionAdd.set("RESOURCEBUTTON_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID"));
        commonService.buildModelCreateInfo(actionAdd);
        metaService.insert(actionAdd);
    }

    @Override
    public FuncInfo getFuncInfo(String funcCode) {
        String currentTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        FuncInfo funcInfo;
        if (Strings.isNullOrEmpty(currentTenantId)) {
            funcInfo = funcInfoCache.getCacheValue(funcCode);
        } else {
            funcInfo = funcInfoCache.getCacheValue(currentTenantId, funcCode);
        }

        if (funcInfo == null) {
            DynaBean funcBean = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder()
                    .eq("FUNCINFO_FUNCCODE", funcCode)
                    .in("FUNCINFO_NODEINFOTYPE", Lists.newArrayList("FUNC", "FUNCFIELD"))
                    .orderByAsc("SY_ORDERINDEX"));

            List<DynaBean> children = metaService.select("JE_CORE_FUNCRELATION", ConditionsWrapper.builder()
                    .eq("FUNCRELATION_ENABLED", "1")
                    .eq("FUNCRELATION_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                    .orderByAsc("SY_ORDERINDEX"));
            List<FuncRelation> funcRelationVos = buildFuncRelations(children);
            funcInfo = buildFuncInfo(funcBean, funcRelationVos);
            if (Strings.isNullOrEmpty(currentTenantId)) {
                funcInfoCache.putCache(funcCode, funcInfo);
            } else {
                funcInfoCache.putCache(currentTenantId, funcCode, funcInfo);
            }
        }
        return funcInfo;
    }

    @Override
    public void buildDefaultFuncInfo(DynaBean funcInfo) {
        DynaBean dynaBean = metaService.selectOneByPk("JE_PRODUCT_MANAGE", funcInfo.getStr("SY_PRODUCT_ID"));
        if (dynaBean != null) {
            funcInfo.set("SY_PRODUCT_CODE", dynaBean.getStr("PRODUCT_CODE"));
            funcInfo.set("SY_PRODUCT_NAME", dynaBean.getStr("PRODUCT_NAME"));
        }
        //更多按钮配置
        if (FuncTypeEnum.TREE.getValue().equals(funcInfo.getStr("FUNCINFO_FUNCTYPE"))) {
            funcInfo.setStr("FUNCINFO_MORE_BUTTON_CONFIG", getDefaultConfigInfo());
            funcInfo.set("FUNCINFO_TREETITLE", "数据结构");
        } else {
            funcInfo.set("FUNCINFO_TREETITLE", "快速查询");
        }
        //关闭拖拽排序
        funcInfo.setStr("FUNCINFO_CLOSE_DRAG_SORT", "0");
        //统计策略
        funcInfo.setStr("FUNCINFO_STATISTICALSTRATEGY", "all");
        //是否启用检索按钮
        funcInfo.setStr("FUNCINFO_OPEN_SEARCH_BUTTON", "1");
        //高级查询-标题宽
        funcInfo.setStr("FUNCINFO_GROUPQUERY_LABEL_WIDTH", "140");
        //表单字段间距
        funcInfo.setStr("FUNCINFO_FORMFIELD_SPACING", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_FORMFIELD_SPACING"), "1"));
        //初始化加载列表数据
        funcInfo.setStr("FUNCINFO_INIT_LOAD_DATA", "1");
        //表单状态
        funcInfo.set("FUNCINFO_FORM_STATE", "edit");
        //手动切换表单展示方案
        funcInfo.set("FUNCINFO_FORM_SHOW_WAY", "0");
        //手动切换表单打印方案
        funcInfo.set("FUNCINFO_ FORM_PRINT_WAY", "0");
        //表单标题
        funcInfo.set("FUNCINFO_FORMTITLE4FUNC", "详细信息");

        //快速查询宽度
        funcInfo.set("FUNCINFO_TREEWIDTH", 230);
        //开启更多按钮
        funcInfo.set("FUNCINFO_OPEN_MORE_BUTTON", "1");
        //子功能高度
        String json = "[{\"text\":\"通用\",\"code\":\"default\",\"value\":0}]";
        funcInfo.set("FUNCINFO_CHILDHEIGHT", StringEscapeUtils.unescapeJava(json));
        //禁用查询元素
        funcInfo.set("FUNCINFO_DISABLEQUERYSQL", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_DISABLEQUERYSQL"), ""));
        //展示审批记录
        funcInfo.set("FUNCINFO_USEWFLOG", "0");
        //启用科技灰皮肤
        funcInfo.set("FUNCINFO_TABLESTYLE", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_TABLESTYLE"), "0"));
        //分组框快速定位
        funcInfo.set("FUNCINFO_GROUP_LOCATION", "1");
        //表单懒加载
        funcInfo.set("FUNCINFO_FORMLAZY", "1");
        //表单隐藏工具条
        funcInfo.set("FUNCINFO_HIDEFORMTBAR", "0");
        //弹出表单显示子功能
        funcInfo.set("FUNCINFO_FORMWINCHILD", "0");
        //弹出字段间距
        funcInfo.set("FUNCINFO_FIELD_SPACING", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_FIELD_SPACING"), "0"));
        //弹出表单位置
        funcInfo.set("FUNCINFO_FORM_POSITION", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_FORM_POSITION"), "center"));
        //表单最小宽度
        funcInfo.set("FUNCINFO_FORMMINWIDTH", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_FORMMINWIDTH"), "1024"));
        //个性化列定义
        funcInfo.set("FUNCINFO_CUSTOM_COLUMN", "0");
        //行编辑
        funcInfo.set("FUNCINFO_LINE_EDIT", "0");
        //隔行变色
        funcInfo.set("FUNCINFO_INTERLACED_DISCOLOUR", "1");
        //数据请求超时
        funcInfo.set("FUNCINFO_GRIDTIMEOUT", 0);
        //行综合展板默认打开
        funcInfo.set("FUNCINFO_GRIDROWTIPSHOW", "0");
        //启用修改标记
        funcInfo.set("FUNCINFO_USEEDIT", "0");
        //启用数据标记
        funcInfo.set("FUNCINFO_USEMARK", "0");
        //启用树形列表视图
        funcInfo.set("FUNCINFO_USETREEGRID", "0");
        //无限滚动
        funcInfo.set("FUNCINFO_GRIDBUFFERED", "0");
        //隐藏工具条
        funcInfo.set("FUNCINFO_HIDEGRIDTBAR", "0");
        //多选过滤
        funcInfo.set("FUNCINFO_CHILDFILTER", "0");
        //拖动排序
        funcInfo.set("FUNCINFO_DDORDER", "0");
        //分页条位置信息
        funcInfo.set("FUNCINFO_PAGEINFOALIGN", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_PAGEINFOALIGN"), "left"));
        //默认行高
        funcInfo.set("FUNCINFO_COLUMN_WIDTH", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_COLUMN_WIDTH"), "small"));
        //FUNCINFO_DISABLE_CHANGE
        funcInfo.set("FUNCINFO_DISABLE_CHANGE", "0");
        //快速查询动态刷新
        funcInfo.set("FUNCINFO_TREEDYNAMICREFRESH", "1");
        //只读流程
        funcInfo.set("FUNCINFO_READONLYWF", "0");
        //列表子功能平级显示
        funcInfo.set("FUNCINFO_GRIDCHILDSS", "0");
        //子功能加载方式
        funcInfo.set("FUNCINFO_CHILDREFRESH", "0");
        //
        funcInfo.set("SY_NODETYPE", "LEAF");
        //数据录入方式
        funcInfo.set("FUNCINFO_INSERTTYPE", "FORM");
        //表单列数
        funcInfo.set("FUNCINFO_FORMCOLS", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_FORMCOLS"), "2"));
        //表单默认宽度
        funcInfo.set("FUNCINFO_FORMDEFWIDTH", "0");
        //排序字段
        funcInfo.set("SY_ORDERINDEX", 1);
        //使用大按钮
        funcInfo.set("FUNCINFO_BIGBUTTON", "0");
        //功能信息没有填完整
        funcInfo.set("FUNCINFO_ISCOMPLETE", "0");
        //单条进卡片
        funcInfo.set("FUNCINFO_OCFORM", "0");
        //新窗口编辑卡片
        funcInfo.set("FUNCINFO_OPENFORM", "0");
        //子卡片横向显示
        funcInfo.set("FUNCINFO_HORIZONTAL", "0");
        //是否启用工作流
        funcInfo.set("FUNCINFO_USEWF", "0");
        //是否启用功能字典
        funcInfo.set("FUNCINFO_FUNCDIC", "0");
        //是否启用附件
        funcInfo.set("FUNCINFO_USEFILES", "0");
        //是否启用页面留痕
        funcInfo.set("FUNCINFO_USEDATALOG", "0");
        //默认启动表单懒加载
        funcInfo.set("FUNCINFO_FORMLAZY", "1");
        //每页展示记录数
        funcInfo.set("FUNCINFO_PAGESIZE", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_PAGESIZE"), "30"));
        //全息查询宽度
        //funcInfo.set("FUNCINFO_QUERYWIDTH", 0);
        //全息查询是否多选
        funcInfo.set("FUNCINFO_MULTIQUERY", "0");
        funcInfo.set("FUNCINFO_ISBOOKMARK", "0");
        //默认不启用表单分页
        funcInfo.set("FUNCINFO_FORMPAGING", "0");
        //一对一表单
        funcInfo.set("FUNCINFO_ONETOFORM", "0");
        //使用向导
        funcInfo.set("FUNCINFO_USEGUIDE", "0");
        //Action
        //funcInfo.set("FUNCINFO_FUNCACTION", "/je/common");
        //子功能展示方式;1-表单横向显示
        funcInfo.set("FUNCINFO_CHILDSHOWTYPE", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_CHILDSHOWTYPE"), "formOuterHorizontal"));
        //录入方式
        funcInfo.set("FUNCINFO_INSERTTYPE", "FORM");
        if (StringUtil.isEmpty(funcInfo.getStr("FUNCINFO_FUNCTYPE", ""))) {
            //功能类型
            funcInfo.set("FUNCINFO_FUNCTYPE", "func");
        }
        //子功能高度
        //funcInfo.set("FUNCINFO_CHILDHEIGHT", "0");
        //表单label宽度
        funcInfo.set("FUNCINFO_FORMLABELWIDTH", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_FORMLABELWIDTH"), "140"));
        //其他语种字段标题宽
        funcInfo.set("FUNCINFO_FORMLABELWIDTH_EN", 140);
        //默认多选
        funcInfo.set("FUNCINFO_MULTISELECT", "1");
        //默认启用分步加载
        funcInfo.set("FUNCINFO_COLUMNLAZY", "1");
        //默认隐藏查询策略
        funcInfo.set("FUNCINFO_GRIDHIDES", "cxcl");

        //默认不启用分步加载
        funcInfo.set("FUNCINFO_SFXDB", "0");
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_TABLESTYLE", "1");
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_VERSION", "0");
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_CHECKUSER", SecurityUserHolder.getCurrentAccountRealUserId());
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_CHECKUSERID", SecurityUserHolder.getCurrentAccountRealUserId());
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_CHECKSTATUS", "DEVELOPOUT");
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_VERSION_DEV", "0");
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_CHECKUSER_DEV", SecurityUserHolder.getCurrentAccountRealUserId());
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_CHECKUSERID_DEV", SecurityUserHolder.getCurrentAccountRealUserName());
        //默认不启用分步加载
        funcInfo.set("FUNCINFO_CHECKSTATUS_DEV", "DEVELOPOUT");
        funcInfo.set("FUNCINFO_USESAAS", "0");
        //高级查询展开 或 高级查询分布加载
        funcInfo.set("FUNCINFO_GROUPFORMOPEN", "0");
        //隐藏表格线
        funcInfo.set("FUNCINFO_GRIDHIDELINES", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_GRIDHIDELINES"), ""));
        funcInfo.set("FUNCINFO_TABLESTYLE", "0");
        //表单宽度
        funcInfo.set("FUNCINFO_FORMWIDTH", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_FORMWIDTH"), "1280"));
        //快速查询分步加载
        funcInfo.set("FUNCINFO_TREEREFRESH", "0");
        //启动简洁按钮条
        funcInfo.set("FUNCINFO_SIMPLEBAR", StringUtil.getDefaultValue(systemSettingRpcService.findSettingValue("FUNCINFO_SIMPLEBAR"), "1"));
        funcInfo.set("FUNCINFO_FORMNAVIGATE", "left");
        //初始化树形功能配置信息
        if (StringUtil.isNotEmpty(funcInfo.getStr("FUNCINFO_TABLENAME"))) {
            DynaBean table = metaBeanService.getResourceTable(funcInfo.getStr("FUNCINFO_TABLENAME"));
            if (!"1".equals(table.getStr("RESOURCETABLE_ISCREATE"))) {
                throw new PlatformException("【" + funcInfo.getStr("FUNCINFO_TABLENAME") + "】表未创建,请先应用表！", PlatformExceptionEnum.JE_CORE_TABLE_ERROR, new Object[]{table});
            }
            if (TableType.TREETABLE.equals(table.getStr("RESOURCETABLE_TYPE")) || "tree".equals(funcInfo.getStr("FUNCINFO_FUNCTYPE"))) {
                //功能类型
                // funcInfo.set("FUNCINFO_FUNCTYPE", "tree");
                List<DynaBean> tableColumns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
                JSONTreeNode template = metaBeanService.buildJSONTreeNodeTemplate(tableColumns);
                Boolean moreRoot = jsonAssist.yesOrNo2boolean(table.getStr("RESOURCETABLE_MOREROOT"));
                JSONArray jsonArray = new JSONArray();
                jsonArray.add(buildJSONObject("id", template.getId(), "主键"));
                jsonArray.add(buildJSONObject("text", template.getText(), "标题"));
                jsonArray.add(buildJSONObject("code", template.getCode(), "编码"));
                jsonArray.add(buildJSONObject("path", template.getNodePath(), "父级主键（内联外建）"));
                jsonArray.add(buildJSONObject("nodeType", template.getNodeType(), "节点类型；普通（GENERAL）,叶子（LEAF）"));
                jsonArray.add(buildJSONObject("moreRoot", moreRoot ? "TRUE" : "FALSE", "是否多根树"));
                jsonArray.add(buildJSONObject("treeOrderIndex", template.getTreeOrderIndex(), "树形排序字段"));
                funcInfo.set("FUNCINFO_FUNCDICCONFIG", jsonArray.toString());
            }
        }
        //默认查询宽度
        funcInfo.set("FUNCINFO_QUERYWIDTH", 150);
        //默认按照父亲路径排序，如果有 SY_CREATETIME 这个字段，则排序默认值为：ORDER BY SY_CREATETIME DESC
        Map<String, String> map = getOrderDefaultValue(funcInfo.getStr("FUNCINFO_TABLENAME"));
        if (map != null) {
            funcInfo.set("FUNCINFO_ORDERSQL", map.get("FUNCINFO_ORDERSQL"));
            funcInfo.setStr("FUNCINFO_ORDERSQL_DES", map.get("FUNCINFO_ORDERSQL_DES"));
        }

    }

    private Map getOrderDefaultValue(String tableCode) {
        if (StringUtil.isEmpty(tableCode)) {
            return null;
        }
        Map<String, String> map = new HashMap<>();
        map.put("FUNCINFO_ORDERSQL", "");
        map.put("FUNCINFO_ORDERSQL_DES", "");
        List<DynaBean> columns = metaService.select("JE_CORE_TABLECOLUMN",
                ConditionsWrapper.builder().eq("TABLECOLUMN_TABLECODE", tableCode));
        for (DynaBean dynaBean : columns) {
            String code = dynaBean.getStr("TABLECOLUMN_CODE");
            String name = dynaBean.getStr("TABLECOLUMN_NAME");
            if ("SY_CREATETIME".equals(code)) {
                map.put("FUNCINFO_ORDERSQL", "ORDER BY SY_CREATETIME DESC");
                map.put("FUNCINFO_ORDERSQL_DES", "ORDER BY " + name + " DESC");
                return map;
            }
        }
        return null;
    }

    private JSONObject buildJSONObject(String key, String value, String desc) {
        JSONObject treeConfig = new JSONObject();
        treeConfig.put("key", key);
        treeConfig.put("value", value);
        treeConfig.put("desc", desc);
        return treeConfig;
    }

    private static String getDefaultConfigInfo() {
        List<ButtonEntity> list = new ArrayStack();
        list.add(new ButtonEntity("添加", "treeInsertBtn", "fal fa-plus", "", "", "button", "1", "", "", "1"));
        list.add(new ButtonEntity("编辑", "treeEditBtn", "jeicon jeicon-edit", "", "", "button", "1", "", "", "1"));
        list.add(new ButtonEntity("删除", "treeRemoveBtn", "jeicon jeicon-times", "", "", "button", "1", "", "", "1"));
        list.add(new ButtonEntity("", "", "", "", "", "divider", "1", "", "", "1"));
        list.add(new ButtonEntity("转移", "treeTransferBtn", "fal fa-folder-upload", "", "", "button", "1", "", "", "1"));
        return JSON.toJSONString(list);
    }

    @Override
    public Map<String, Object> getFuncConfigInfo(DynaBean funcBean) {
        Map<String, Object> resultObj = Maps.newHashMap();
        //需要重新构建，构建子功能信息
        List<DynaBean> children = metaService.select("JE_CORE_FUNCRELATION", ConditionsWrapper.builder()
                .eq("FUNCRELATION_ENABLED", "1")
                .eq("FUNCRELATION_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .orderByAsc("SY_ORDERINDEX"));
        List<FuncRelation> funcRelationVos = buildFuncRelations(children);

        //构建功能信息
        FuncInfo funcInfo = buildFuncInfo(funcBean, funcRelationVos);
        //构建功能配置信息
        Map<String, Object> funcConfig = buildFuncConfigInfo(funcBean, funcInfo, children);

        String currentTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        //构建功能全量结果集
        resultObj.put("func", funcConfig);
        resultObj.put("lastVersion", funcInfo.getLastVersion());
        if (Strings.isNullOrEmpty(currentTenantId)) {
            funcConfigCache.putCache(funcInfo.getFuncCode(), resultObj);
            funcInfoCache.putCache(funcInfo.getFuncCode(), funcInfo);
        } else {
            resultObj.put("zhId", currentTenantId);
            funcConfigCache.putCache(currentTenantId, funcInfo.getFuncCode(), resultObj);
            funcInfoCache.putCache(currentTenantId, funcInfo.getFuncCode(), funcInfo);
        }
        resultObj.put("funcInfo", funcInfo);
        return resultObj;
    }

    @Override
    @Transactional
    public DynaBean updateFunInfo(DynaBean funcInfo) {

        String FUNCINFO_WHERESQL = funcInfo.getStr("FUNCINFO_WHERESQL");
        String FUNCINFO_ORDERSQL = funcInfo.getStr("FUNCINFO_ORDERSQL");

        String errotResult = "";
        if (!StringUtil.isEmpty(FUNCINFO_WHERESQL)) {
            errotResult = checkSql(FUNCINFO_WHERESQL, "where");
            if (!StringUtil.isEmpty(errotResult)) {
                throw new PlatformException(MessageUtils.getMessage("function.config.funcinfowheresql.error"), PlatformExceptionEnum.JE_CORE_TABLE_CHECKCOLUMN_ERROR);
            }
        }

        if (!StringUtil.isEmpty(FUNCINFO_ORDERSQL)) {
            errotResult = checkSql(FUNCINFO_ORDERSQL, "order");
            if (!StringUtil.isEmpty(errotResult)) {
                throw new PlatformException(MessageUtils.getMessage("function.config.funcinfoordersql.error"), PlatformExceptionEnum.JE_CORE_TABLE_CHECKCOLUMN_ERROR);
            }
        }


        String funcCode = funcInfo.getStr("FUNCINFO_FUNCCODE");
        String funcId = funcInfo.getStr("JE_CORE_FUNCINFO_ID");
        if ("FUNC".equals(funcInfo.getStr("FUNCINFO_NODEINFOTYPE")) || "FUNCFIELD".equals(funcInfo.getStr("FUNCINFO_NODEINFOTYPE"))) {
            List<DynaBean> lists = metaService.select("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", funcCode).ne("JE_CORE_FUNCINFO_ID", funcId));
            if (lists.size() > 0) {
                return null;
            }
            if ("0".equals(funcInfo.get("FUNCINFO_ISCOMPLETE")) && StringUtil.isNotEmpty(funcInfo.getStr("FUNCINFO_TABLENAME"))) {
                funcInfo.set("FUNCINFO_ISCOMPLETE", "1");
                initFuncInfo(funcInfo);
            }
            if ("1".equals(funcInfo.getStr("FUNCINFO_USEWF"))) {
                try {
                    initProcessInfo(funcInfo);
                } catch (APIWarnException e) {
                    e.printStackTrace();
                }
            }
            /**
             * 启用审核功能
             */
            if ("1".equals(funcInfo.getStr("FUNCINFO_ENABLEDSH"))) {
                initShInfo(funcInfo);
            }
        }
        commonService.buildModelModifyInfo(funcInfo);
        metaService.update(funcInfo);
        return funcInfo;
    }

    private String checkSql(String code, String type) {
        String sqlT = "";
        /**
         * 将连续空格替换为一个空格
         */
        code = code.replaceAll("\\s+", " ");
        if ("where".equals(type)) {
            sqlT = "and ";
            try {
                code = code.trim().substring(0, 5);
            } catch (Exception e) {
                return MessageUtils.getMessage("function.wheresql.error");
            }
            if (!(code.toLowerCase()).contains(sqlT)) {
                return MessageUtils.getMessage("function.wheresql.error");
            }
        }
        if ("order".equals(type)) {
            sqlT = "order by ";
            try {
                code = code.trim().substring(0, 10);
            } catch (Exception e) {
                return MessageUtils.getMessage("function.ordersql.error");
            }
            if (!(code.toLowerCase()).contains(sqlT)) {
                return MessageUtils.getMessage("function.ordersql.error");
            }
        }
        return null;
    }

    @Override
    @Transactional
    public void removeFuncInfoById(String funcId) {
        DynaBean fun = metaService.selectOneByPk("JE_CORE_FUNCINFO", funcId);
        String parentId = fun.getStr("SY_PARENT");
        String funcCode = fun.getStr("FUNCINFO_FUNCCODE");
        //菜单功能关系表
        metaService.delete("JE_META_MENUFUNC",
                ConditionsWrapper.builder().eq("JE_CORE_FUNCINFO_ID", funcId));
        //数据授权
        metaService.delete("JE_CORE_FUNCPERM",
                ConditionsWrapper.builder().eq("FUNCPERM_FUNCINFO_ID", funcId));
        //功能
        metaService.delete("JE_CORE_FUNCINFO",
                ConditionsWrapper.builder().eq("JE_CORE_FUNCINFO_ID", funcId));

        //删除菜单
        metaRbacService.deleteByTableCodeAndNativeQuery("JE_CORE_MENU",
                NativeQuery.build().eq("MENU_NODEINFO", funcCode));

        //清空静态化缓存
        String currentTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        if (Strings.isNullOrEmpty(currentTenantId)) {
            funcInfoCache.removeCache(funcCode);
            funcStaticizeCache.removeCache(funcCode);
        } else {
            funcInfoCache.removeCache(currentTenantId, funcCode);
            funcStaticizeCache.removeCache(currentTenantId, funcCode);
        }

        //处理父功能
        List<DynaBean> children = metaService.select("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("SY_PARENT", parentId));
        if (children.size() <= 0) {
            String updateSql = "UPDATE JE_CORE_FUNCINFO SET SY_NODETYPE='LEAF' where JE_CORE_FUNCINFO_ID='" + parentId + "'";
            metaService.executeSql(updateSql);
        }
    }

    @Override
    public String buildWhereSql4funcRelation(List<FuncRelationField> relatedFields, DynaBean dynaBean) {
        StringBuffer whereSql = new StringBuffer();
        String tableCode = dynaBean.getStr(BeanService.KEY_TABLE_CODE);
        HashMap values = dynaBean.getValues();
        for (FuncRelationField relatedField : relatedFields) {
//			JSONObject relatedField=(JSONObject) refieldObj;
            String diySql = relatedField.getDiySql();
//					relatedField.getString("ASSOCIATIONFIELD_SQL");
            if (StringUtil.isNotEmpty(diySql)) {
                whereSql.append(StringUtil.parseKeyWord(diySql, values.entrySet()));
            } else if (relatedField.getWhereChild()) {
                String association = relatedField.getWhereType();
                String value = dynaBean.getStr(relatedField.getFieldCode(), "");
                if (StringUtil.isNotEmpty(association) && !"no".equalsIgnoreCase(association)) {
                    whereSql.append(" AND " + relatedField.getChildFieldCode() + " " + association);
                    if (SqlUtil.IN.equalsIgnoreCase(association) || SqlUtil.NOT_IN.equalsIgnoreCase(association)) {
                        whereSql.append(" (" + StringUtil.buildArrayToString(value.split(",")) + ") ");
                    } else if (SqlUtil.LIKE.equalsIgnoreCase(association)) {
                        whereSql.append(" '%" + value + "%' ");
                    } else {
                        whereSql.append(" '" + value + "' ");
                    }
                }
            }
        }
        dynaBean.set(BeanService.KEY_TABLE_CODE, tableCode);
        return whereSql.toString();
    }

    @Override
    @Transactional
    public DynaBean clearFuncInfo(DynaBean funcInfo) {
        // permissionRpcService.clearPermData(PermType.MT, funcInfo.getStr("JE_CORE_FUNCINFO_ID"), true);
        DynaBean db = metaService.selectOneByPk("JE_CORE_FUNCINFO", funcInfo.getStr("JE_CORE_FUNCINFO_ID"));
        funcInfo.setStr("FUNCINFO_FUNCCODE", db.getStr("FUNCINFO_FUNCCODE"));
        funcInfo.set("FUNCINFO_PKNAME", "");
        funcInfo.set("FUNCINFO_TABLENAME", "");
        funcInfo.set("FUNCINFO_ENTITYNAME", "");
        funcInfo.set("FUNCINFO_EXPANDENTITYNAME", "");
        funcInfo.set("FUNCINFO_GRIDFILTER", "");
        funcInfo.set("FUNCINFO_FORMDEFWIDTH", "");
        funcInfo.set("FUNCINFO_FORMTITLE", "");
        funcInfo.set("FUNCINFO_FORMCOLS", "");
        funcInfo.set("FUNCINFO_ISCOMPLETE", "0");
        funcInfo.set("FUNCINFO_OCFORM", "");
        funcInfo.set("FUNCINFO_OPENFORM", "");
        funcInfo.set("FUNCINFO_HORIZONTAL", "");
        funcInfo.set("FUNCINFO_FUNCDIC", "");
        funcInfo.set("FUNCINFO_FUNCDICCONFIG", "");
        funcInfo.set("FUNCINFO_CHARTSOPEN", "");
        //不启用工作流，因为工作流是复制不过来
        funcInfo.set("FUNCINFO_USEWF", "0");
        funcInfo.set("FUNCINFO_USEFILES", "");
        funcInfo.set("FUNCINFO_USEDATALOG", "");
        funcInfo.set("FUNCINFO_ORDERSQL", "");
        funcInfo.set("FUNCINFO_EXPANDPANELS", "");
        funcInfo.set("FUNCINFO_FORMPAGING", "");
        funcInfo.set("FUNCINFO_FORMPAGINGCONFIG", "");
        funcInfo.set("FUNCINFO_CHILDHEIGHT", 0);
        funcInfo.set("FUNCINFO_GROUPFIELD", "");
        funcInfo.set("FUNCINFO_GROUPFIELDTPL", "");
        funcInfo.set("FUNCINFO_BIGBUTTON", "");
        funcInfo.set("FUNCINFO_BOOKMARKCONFIG", "");
        funcInfo.set("FUNCINFO_ISBOOKMARK", "");
        funcInfo.set("FUNCINFO_ISSTATIC", "");
        funcInfo.set("FUNCINFO_MULTIQUERY", "");
        funcInfo.set("FUNCINFO_FORMLABELWIDTH", "");
        funcInfo.set("FUNCINFO_DATASOURCE", "");
        funcInfo.set("FUNCINFO_ATTACHMENTPATH", "");
        funcInfo.set("FUNCINFO_PAGESIZE", "");
        //子功能展示方式
        funcInfo.set("FUNCINFO_CHILDSHOWTYPE", "");
        //录入方式
        funcInfo.set("FUNCINFO_INSERTTYPE", "");
        //功能类型
        funcInfo.set("FUNCINFO_FUNCTYPE", "");
        //构建默认数据
        buildDefaultFuncInfo(funcInfo);
        funcInfo.set(BeanService.KEY_TABLE_CODE, "JE_CORE_FUNCINFO");
        metaService.update(funcInfo);
        //删除信息
        String funcId = funcInfo.getStr("JE_CORE_FUNCINFO_ID");
        //解除软连接关系
        List<DynaBean> relyonFuncs = metaFuncRelyonService.getRelyons(funcId);
        for (DynaBean relyonFunc : relyonFuncs) {
            String sql = "DELETE FROM JE_CORE_FUNCRELYON WHERE FUNCRELYON_FUNCINFO_ID='" + relyonFunc.getStr("JE_CORE_FUNCRELYON_ID") + "' AND FUNCRELYON_FUNCID='" + funcId + "'";
            metaService.executeSql(sql);
        }
        //关联字段
        String delAssFieldSql = " DELETE FROM JE_CORE_ASSOCIATIONFIELD WHERE ASSOCIATIONFIELD_FID='" + funcId + "'";
        metaService.executeSql(delAssFieldSql);
        //子功能
        String delChildSql = "DELETE FROM JE_CORE_FUNCRELATION WHERE FUNCRELATION_FUNCINFO_ID='" + funcId + "'";
        metaService.executeSql(delChildSql);
        //按钮
        String delBtnSql = "DELETE FROM JE_CORE_RESOURCEBUTTON WHERE RESOURCEBUTTON_FUNCINFO_ID='" + funcId + "'";
        metaService.executeSql(delBtnSql);
        //字段
        String delFieldSql = "DELETE FROM JE_CORE_RESOURCEFIELD WHERE RESOURCEFIELD_FUNCINFO_ID='" + funcId + "'";
        metaService.executeSql(delFieldSql);
        //表格列
        String delColumnSql = "DELETE FROM JE_CORE_RESOURCECOLUMN WHERE RESOURCECOLUMN_FUNCINFO_ID='" + funcId + "'";
        metaService.executeSql(delColumnSql);
        String delRelyonSql = "DELETE FROM JE_CORE_FUNCRELYON WHERE FUNCRELYON_FUNCINFO_ID='" + funcId + "'";
        metaService.executeSql(delRelyonSql);
        String delQuerySql = "DELETE FROM JE_CORE_QUERYSTRATEGY WHERE QUERYSTRATEGY_FUNCINFO_ID='" + funcId + "'";
        metaService.executeSql(delQuerySql);
        String delGroupQuerySql = "DELETE FROM JE_CORE_GROUPQUERY WHERE GROUPQUERY_GNID='" + funcId + "'";
        metaService.executeSql(delGroupQuerySql);

        //请空静态化缓存
        String currentTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        if (Strings.isNullOrEmpty(currentTenantId)) {
            funcInfoCache.removeCache(funcInfo.getStr("FUNCINFO_FUNCCODE"));
            funcStaticizeCache.removeCache(funcInfo.getStr("FUNCINFO_FUNCCODE"));
        } else {
            funcInfoCache.removeCache(currentTenantId, funcInfo.getStr("FUNCINFO_FUNCCODE"));
            funcStaticizeCache.removeCache(currentTenantId, funcInfo.getStr("FUNCINFO_FUNCCODE"));
        }
        return funcInfo;
    }

    @Override
    @Transactional
    public void initFuncInfo(DynaBean funcInfo) {
        String funcId = funcInfo.getStr("JE_CORE_FUNCINFO_ID");
        implButton(funcInfo, funcId);
        String tableCode = funcInfo.getStr("FUNCINFO_TABLENAME");
        String funcType = funcInfo.getStr("FUNCINFO_FUNCTYPE");
        try {
            if (StringUtil.isNotEmpty(tableCode)) {
                if (StringUtils.countMatches(tableCode, ".") > 1) {
                    Class c = Class.forName(tableCode);
                    Annotation entity = c.getAnnotation(Entity.class);
                    if (entity != null) {
                        metaResColumnService.impl(funcId, c);
                    }
                } else {
                    metaResColumnService.implDyanBean(funcId, tableCode);
                }
            } else if ("procedure".equals(funcType)) {
                funcInfo.set("FUNCINFO_GROUPFORMOPEN", "1");
                metaResColumnService.implProcedure(funcInfo);
            } else if ("iditprocedure".equals(funcType)) {
                funcInfo.set("FUNCINFO_GROUPFORMOPEN", "1");
                metaResColumnService.implIditProcedure(funcInfo);
            } else if ("sql".equals(funcType)) {
                funcInfo.set("FUNCINFO_GROUPFORMOPEN", "1");
                metaResColumnService.implSql(funcInfo);
            }
        } catch (Exception e) {
            throw new PlatformException("初始化功能异常", PlatformExceptionEnum.JE_FUNCINFO_FUNCINIT_ERROR, new Object[]{funcInfo}, e);
        }
    }

    @Override
    @Transactional
    public void removeFuncRelyon(String funcRelyonId) {
        DynaBean funcRelyon = metaService.selectOneByPk("JE_CORE_FUNCRELYON", funcRelyonId);
        if (funcRelyon != null) {
            metaService.executeSql("DELETE FROM JE_CORE_FUNCRELYON WHERE FUNCRELYON_FUNCID='" + funcRelyon.getStr("FUNCRELYON_FUNCINFO_ID") + "' AND FUNCRELYON_FUNCINFO_ID='" + funcRelyon.getStr("FUNCRELYON_FUNCID") + "'");
            metaService.executeSql("DELETE FROM JE_CORE_FUNCRELYON WHERE JE_CORE_FUNCRELYON_ID='" + funcRelyonId + "'");
        }
    }

    @Override
    @Transactional
    public DynaBean treeMove(DynaBean dynaBean) {
        String tableCode = dynaBean.getStr(BeanService.KEY_TABLE_CODE);
        String pkName = dynaBean.getStr(BeanService.KEY_PK_CODE);
        DynaBean bean = metaService.selectOneByPk(tableCode, dynaBean.getStr(pkName), pkName + ",SY_PATH,SY_PARENTPATH,SY_PARENTPATH,SY_LAYER,SY_PARENT");
        String newParentId = dynaBean.getStr("SY_PARENT");
        String oldParentId = bean.getStr("SY_PARENT");
        String oldPath = bean.getStr("SY_PATH");
        String oldParentPath = bean.getStr("SY_PARENTPATH");
        Integer chaLayer = dynaBean.getInt("SY_LAYER", 0) - bean.getInt("SY_LAYER", 0);
        bean.set("SY_PATH", dynaBean.getStr("SY_PATH") + "/" + dynaBean.getStr(pkName));
        bean.set("SY_PARENTPATH", dynaBean.getStr("SY_PATH"));
        bean.set("SY_PARENT", newParentId);
        bean.set("SY_LAYER", dynaBean.get("SY_LAYER"));
        bean.set(BeanService.KEY_TABLE_CODE, tableCode);
        //更新当前节点下所有孩子的路径信息
        metaService.executeSql("UPDATE " + tableCode + " SET SY_PATH=REPLACE(SY_PATH,'" + oldPath + "','" + bean.getStr("SY_PATH") + "'),SY_PARENTPATH=REPLACE(SY_PARENTPATH,'" + oldParentPath + "','" + bean.getStr("SY_PARENTPATH") + "'),SY_LAYER=(SY_LAYER+" + chaLayer + ") WHERE SY_PATH LIKE '%" + oldPath + "%' AND " + pkName + "!='" + dynaBean.getStr(pkName) + "'");
        metaService.update(bean);
        commonService.updateTreePanent4NodeType("JE_CORE_FUNCINFO", newParentId);
        commonService.updateTreePanent4NodeType("JE_CORE_FUNCINFO", oldParentId);
        return bean;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void syncConfig(DynaBean dynaBean) {
        String toFuncCode = dynaBean.getStr("toFuncCode");
        String formFuncCode = dynaBean.getStr("formFuncCode");
        //String toPlanId = dynaBean.getStr("toPlanId");
        //String fromPlanId = dynaBean.getStr("fromPlanId");
        String columnCodes = dynaBean.getStr("columnCodes");
        String type = dynaBean.getStr("type");


        //目标功能
        DynaBean fromFunc = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", formFuncCode));
        if (fromFunc == null) {
            throw new PlatformException("目标功能未找到！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        //当前功能
        DynaBean func = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", toFuncCode));
        if (func == null) {
            throw new PlatformException("功能未找到！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        //目标列集合
        List<DynaBean> targetColumn = metaService.select("JE_CORE_RESOURCECOLUMN",
                ConditionsWrapper.builder().eq("RESOURCECOLUMN_FUNCINFO_ID", fromFunc.getStr("JE_CORE_FUNCINFO_ID")));
        //当前列集合
        List<DynaBean> currentColumn = metaService.select("JE_CORE_RESOURCECOLUMN",
                ConditionsWrapper.builder().eq("RESOURCECOLUMN_FUNCINFO_ID", func.getStr("JE_CORE_FUNCINFO_ID")));
        //目标字段集合
        List<DynaBean> targetField = metaService.select("JE_CORE_RESOURCEFIELD",
                ConditionsWrapper.builder().eq("RESOURCEFIELD_FUNCINFO_ID", fromFunc.getStr("JE_CORE_FUNCINFO_ID")));
        //当前字段集合
        List<DynaBean> currentField = metaService.select("JE_CORE_RESOURCEFIELD",
                ConditionsWrapper.builder().eq("RESOURCEFIELD_FUNCINFO_ID", func.getStr("JE_CORE_FUNCINFO_ID")));
        //同步列表
        new SyncConfigManage(targetColumn, currentColumn, columnSyncConfigService, type, columnCodes).excuteSync();
        //同步字段
        new SyncConfigManage(targetField, currentField, fieldSyncConfigService, type, columnCodes).excuteSync();
    }


    /**
     * 初始化流程信息
     *
     * @param funcInfo
     */
    @Transactional
    public void initProcessInfo(DynaBean funcInfo) throws APIWarnException {
        //加入字段
        String tableCode = funcInfo.getStr("FUNCINFO_TABLENAME");
        /**
         * 这里注释掉的原因在于流程实际是配置在视图上的，所以即使自动扩展了操作表，视图也不会存在流程字段，所以正确的流程应该是：
         * 开发人员手动配置过程中，一定要却要视图中存在流程字段，且流程流转过程中更新的流程状态字段必须为操作表的流程字段。
         * 综上，此处的逻辑应该是如果是视图，则操作的还是视图，视图是无需自动增加字段的
         */
//        if (FuncTypeEnum.VIEW.getValue().equals(funcInfo.getStr("FUNCINFO_FUNCTYPE"))) {
//            tableCode = funcInfo.getStr("FUNCINFO_CRUDTABLENAME");
//        }
        if(FuncTypeEnum.VIEW.getValue().equals(funcInfo.getStr("FUNCINFO_FUNCTYPE"))){
            return;
        }
        DynaBean table = metaService.selectOne("JE_CORE_RESOURCETABLE", ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", tableCode));
        Long count = metaService.countBySql(ConditionsWrapper.builder().table("JE_CORE_TABLECOLUMN").in("TABLECOLUMN_CODE", "SY_AUDFLAG,SY_PIID,SY_PDID").eq("TABLECOLUMN_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID")));
        if (count < 3) {
            metaTableColumnService.initWfBaseColumns(table);
            if (PRODUCT_CORE_META.equals(table.getStr("SY_PRODUCT_CODE"))) {
                metaTableService.updateTable(table.getStr("JE_CORE_RESOURCETABLE_ID"), true);
            } else {
                PCDataService pCDataService = RpcSchemaFactory.getRemoteProvierClazz(table.getStr("SY_PRODUCT_CODE"),
                        "pCDataService", PCDataService.class);
                List<DbModel> dbModels = pCDataService.loadTableColumnBySql(tableCode);
                List<String> ddl = metaTableService.generateUpdateDDL(table.getStr("JE_CORE_RESOURCETABLE_ID"), dbModels);
                CommonTableRpcService commonTableRpcService = RpcSchemaFactory.getRemoteProvierClazz(table.getStr("SY_PRODUCT_CODE"),
                        "commonTableRpcService", CommonTableRpcService.class);
                commonTableRpcService.executeSql(ddl, tableCode);
                metaTableService.afterTableUpdated(table.getStr("JE_CORE_RESOURCETABLE_ID"));
            }
        }
    }

    @Transactional
    public void initShInfo(DynaBean funcInfo) {
        //增加按鈕
//		DynaBean funcInfo=serviceTemplate.selectOneByPk("JE_CORE_FUNCINFO", funcId);
        String pkCode = funcInfo.getStr("FUNCINFO_PKNAME");
        String funcId = funcInfo.getStr("JE_CORE_FUNCINFO_ID");
        List<DynaBean> buttons = metaService.select("JE_CORE_RESOURCEBUTTON", ConditionsWrapper.builder()
                .eq("RESOURCEBUTTON_FUNCINFO_ID", funcId)
                .in("RESOURCEBUTTON_CODE", Lists.newArrayList("formSubmitBtn", "formCacelBtn")));
        if (buttons == null || buttons.size() <= 0) {
            DynaBean formSave = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
            formSave.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
            formSave.set("RESOURCEBUTTON_CODE", "formSubmitBtn");
            formSave.set("RESOURCEBUTTON_NAME", "审核");
            //可用   true
            formSave.set("RESOURCEBUTTON_DISABLED", "0");
            //表单按钮
            formSave.set("RESOURCEBUTTON_ISFORM", "1");
            formSave.set("RESOURCEBUTTON_HIDDEN", "0");
            formSave.set("RESOURCEBUTTON_TYPE", "FORM");
            ;
            formSave.set("RESOURCEBUTTON_BIGICONCLS", "list_save_32_3");
            //绑定表单验证   false
            formSave.set("RESOURCEBUTTON_FORMBIND", "1");
            //按钮样式
            formSave.set("RESOURCEBUTTON_ICON", "fal fa-arrow-right");
            formSave.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-arrow-right");
            formSave.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C01");
            formSave.set("SY_ORDERINDEX", 8);
            formSave.set("RESOURCEBUTTON_SYSMODE", "");
            formSave.set("RESOURCEBUTTON_FUNCINFO_ID", funcId);
            formSave.set("RESOURCEBUTTON_INTERPRETER", "");
            formSave.setStr("RESOURCEBUTTON_BGCOLOR", "#FFFFFF");
            formSave.setStr("RESOURCEBUTTON_FONTCOLOR", "#3F3F3F");
            formSave.setStr("RESOURCEBUTTON_BORDERCOLOR", "#D9D9D9");
            formSave.set("RESOURCEBUTTON_INTERPRETER", "JE.useUtils().isNotEmpty('{" + pkCode + "}') && '1'!='{SY_ACKFLAG}' ");
            commonService.buildModelCreateInfo(formSave);
            metaService.insert(formSave);
            DynaBean cacelBtn = new DynaBean("JE_CORE_RESOURCEBUTTON", false);
            cacelBtn.set(BeanService.KEY_PK_CODE, "JE_CORE_RESOURCEBUTTON_ID");
            cacelBtn.set("RESOURCEBUTTON_CODE", "formCancelBtn");
            cacelBtn.set("RESOURCEBUTTON_NAME", "弃审");
            //可用   true
            cacelBtn.set("RESOURCEBUTTON_DISABLED", "0");
            //表单按钮
            cacelBtn.set("RESOURCEBUTTON_ISFORM", "1");
            cacelBtn.set("RESOURCEBUTTON_HIDDEN", "0");
            cacelBtn.set("RESOURCEBUTTON_NOREADONLY", "1");
            cacelBtn.set("RESOURCEBUTTON_TYPE", "FORM");
            ;
            cacelBtn.set("RESOURCEBUTTON_BIGICONCLS", "list_save_32_3");
            //绑定表单验证   false
            cacelBtn.set("RESOURCEBUTTON_FORMBIND", "1");
            //按钮样式
            cacelBtn.set("RESOURCEBUTTON_ICON", "jeicon jeicon-return-withdraw");
            cacelBtn.set("RESOURCEBUTTON_FONTICONCLS", "fa fa-repeat");
            cacelBtn.set("RESOURCEBUTTON_CLS", "JEPLUS_B_C01");
            cacelBtn.set("SY_ORDERINDEX", 9);
            cacelBtn.set("RESOURCEBUTTON_SYSMODE", "");
            cacelBtn.set("RESOURCEBUTTON_FUNCINFO_ID", funcId);
            cacelBtn.set("RESOURCEBUTTON_INTERPRETER", "");
            cacelBtn.setStr("RESOURCEBUTTON_BGCOLOR", "#FFFFFF");
            cacelBtn.setStr("RESOURCEBUTTON_FONTCOLOR", "#3F3F3F");
            cacelBtn.setStr("RESOURCEBUTTON_BORDERCOLOR", "#D9D9D9");
            cacelBtn.set("RESOURCEBUTTON_INTERPRETER", "JE.useUtils().isNotEmpty('{" + pkCode + "}') && '1'=='{SY_ACKFLAG}' ");
            commonService.buildModelCreateInfo(cacelBtn);
            metaService.insert(cacelBtn);

            //按钮授权
            Map<String, List<String>> funcButtonMap = new HashMap<>();
            funcButtonMap.put(funcInfo.getStr("FUNCINFO_FUNCCODE"), Lists.newArrayList("formSubmitBtn", "formCancelBtn"));
            permissionRpcService.quickGrantFuncButton(funcInfo.getStr("SY_PRODUCT_ID"), funcButtonMap);
        }
        String tableCode = funcInfo.getStr("FUNCINFO_TABLENAME");
        DynaBean table = metaService.selectOne("JE_CORE_RESOURCETABLE", ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", tableCode).notIn("MODULE"));
        long tableCount = metaService.countBySql(ConditionsWrapper.builder().table("JE_CORE_TABLECOLUMN").eq("TABLECOLUMN_CODE", "SY_ACKFLAG").eq("TABLECOLUMN_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID")));
        String productCode = table.getStr("SY_PRODUCT_CODE");
        if (tableCount <= 0) {
            metaTableColumnService.initShColumns(table);
            if (PRODUCT_CORE_META.equals(productCode)) {
                metaTableService.updateTable(table.getStr("JE_CORE_RESOURCETABLE_ID"), true);
            } else {
                UpgradeModulePackageRpcService upgradeModulePackageRpcService = RpcSchemaFactory.getRemoteProvierClazz(productCode,
                        "upgradeModulePackageRpcService", UpgradeModulePackageRpcService.class);
                List<DbModel> dbModels = upgradeModulePackageRpcService.loadTableColumnBySql(table.getStr("RESOURCETABLE_TABLECODE"));
                List<String> sqlList = tableService.generateUpdateDDL(table.getStr("JE_CORE_RESOURCETABLE_ID"), dbModels);
                upgradeModulePackageRpcService.executeSql(sqlList);
                tableService.afterTableUpdated(table.getStr("JE_CORE_RESOURCETABLE_ID"));
            }

            //加入查询策略
        }
    }

    private List<FuncRelation> buildFuncRelations(List<DynaBean> children) {
        List<FuncRelation> funcRelationVos = Lists.newArrayList();
        for (DynaBean funRelation : children) {
            FuncRelation funcRelationVo = new FuncRelation();
            funcRelationVo.setName(funRelation.getStr("FUNCRELATION_NAME"));
            funcRelationVo.setCode(funRelation.getStr("FUNCRELATION_CODE"));
            funcRelationVo.setTableCode(funRelation.getStr("FUNCRELATION_TABLENAME"));
            funcRelationVo.setType(funRelation.getStr("SY_STATUS"));
            funcRelationVo.setCopyChild(jsonAssist.yesOrNo2boolean(funRelation.getStr("FUNCRELATION_COPY")));

            List<DynaBean> assoFields = metaService.select("JE_CORE_ASSOCIATIONFIELD", ConditionsWrapper.builder()
                    .eq("ASSOCIATIONFIELD_FUNCRELAT_ID", funRelation.getStr("JE_CORE_FUNCRELATION_ID"))
                    .orderByAsc("SY_ORDERINDEX"));
            //关联字段
            funRelation.set("relatedFields", jsonBuilder.buildDynaValues(assoFields));
            List<FuncRelationField> funcRelationFields = new ArrayList<>();
            for (DynaBean assoField : assoFields) {
                FuncRelationField funcRelationField = new FuncRelationField();
                funcRelationField.setFieldCode(assoField.getStr("ASSOCIATIONFIELD_PRIFIELDCODE"));
                funcRelationField.setChildFieldCode(assoField.getStr("ASSOCIATIONFIELD_CHIFIELDCODE"));
                funcRelationField.setDiySql(assoField.getStr("ASSOCIATIONFIELD_SQL"));
                funcRelationField.setWhereType(assoField.getStr("ASSOCIATIONFIELD_ASSOCIATION"));
                funcRelationField.setWhereChild(jsonAssist.yesOrNo2boolean(assoField.getStr("ASSOCIATIONFIELD_WHERECON")));
                funcRelationField.setDoValue(jsonAssist.yesOrNo2boolean(assoField.getStr("ASSOCIATIONFIELD_TRANSMIT")));
                funcRelationField.setDeleteChild(jsonAssist.yesOrNo2boolean(assoField.getStr("ASSOCIATIONFIELD_DELCHILD")));
                funcRelationField.setUpdateChild(jsonAssist.yesOrNo2boolean(assoField.getStr("ASSOCIATIONFIELD_CASCADEUPDATE")));
                funcRelationFields.add(funcRelationField);
            }
            funcRelationVo.setChildFields(funcRelationFields);
            funcRelationVos.add(funcRelationVo);
        }
        return funcRelationVos;
    }

    /**
     * 构建功能VO信息
     *
     * @param funcBean 功能Bean
     * @return
     */
    private FuncInfo buildFuncInfo(DynaBean funcBean, List<FuncRelation> funcRelationVos) {
        FuncInfo funcInfoVo = new FuncInfo();
        Map<String, String> fieldDefalutInfos = new HashMap<>();
        List<String> lazyColumnCodes = new ArrayList<String>();

        //功能是否延迟加载
        boolean columnLazy = jsonAssist.yesOrNo2boolean(funcBean.getStr("FUNCINFO_COLUMNLAZY", "0"));

        //构建VO缓存信息
        funcInfoVo.setFuncBucket(funcBean.getStr("FUNCINFO_ATTACHMENTPATH"));
        funcInfoVo.setTreeFuncConfig(funcBean.getStr("FUNCINFO_FUNCDICCONFIG"));
        funcInfoVo.setChildren(funcRelationVos);
        funcInfoVo.setFuncId(funcBean.getStr("JE_CORE_FUNCINFO_ID"));
        funcInfoVo.setFuncName(funcBean.getStr("FUNCINFO_FUNCNAME"));
        funcInfoVo.setFuncCode(funcBean.getStr("FUNCINFO_FUNCCODE"));
        funcInfoVo.setTableCode(funcBean.getStr("FUNCINFO_TABLENAME"));
        funcInfoVo.setPkCode(funcBean.getStr("FUNCINFO_PKNAME"));
        funcInfoVo.setCurdTableCode(funcBean.getStr("FUNCINFO_CRUDTABLENAME"));
        funcInfoVo.setIconCls(funcBean.getStr("FUNCINFO_ICON"));
        funcInfoVo.setFuncType(funcBean.getStr("FUNCINFO_FUNCTYPE"));
        funcInfoVo.setWhereSql(funcBean.getStr("FUNCINFO_WHERESQL"));
        funcInfoVo.setOrderSql(funcBean.getStr("FUNCINFO_ORDERSQL"));
        String otherConfigStr = funcBean.getStr("FUNCINFO_OTHERCONFIG");
        //增加扩展配置，用于安全处理货其他扩展配置处理
        funcInfoVo.setOtherConfig(otherConfigStr);
        if (StringUtil.isNotEmpty(otherConfigStr)) {
            JSONObject obj = JSON.parseObject(otherConfigStr);
            if (obj.containsKey("titleConfig")) {
                funcInfoVo.setPostilTitleConfig(obj.getString("titleConfig"));
            }
            if (obj.containsKey("showConfig")) {
                funcInfoVo.setPostilShowConfig(obj.getString("showConfig"));
            }
        }

        //2.初始化功能-->表单信息
        List<DynaBean> fields = metaService.select("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder()
                .eq("RESOURCEFIELD_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .orderByAsc("SY_ORDERINDEX"));
        for (DynaBean field : fields) {
            String defaultVal = field.getStr("RESOURCEFIELD_VALUE", "");
            String fieldCode = field.getStr("RESOURCEFIELD_CODE");
            if (StringUtil.isNotEmpty(defaultVal)) {
                fieldDefalutInfos.put(fieldCode, defaultVal);
            }
        }

        List<DynaBean> columns = metaService.select("JE_CORE_RESOURCECOLUMN", ConditionsWrapper.builder()
                .eq("RESOURCECOLUMN_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .orderByAsc("SY_ORDERINDEX"));
        for (DynaBean column : columns) {
            if (columnLazy && "1".equals(column.getStr("RESOURCECOLUMN_LAZYLOAD"))) {
                lazyColumnCodes.add(column.getStr("RESOURCECOLUMN_CODE"));
            }
        }

        funcInfoVo.setFieldDefaultValues(fieldDefalutInfos);
        funcInfoVo.setQueryColumns(Joiner.on(",").join(lazyColumnCodes));
        funcInfoVo.setPostil(false);
        funcInfoVo.setMark(jsonAssist.yesOrNo2boolean(funcBean.getStr("FUNCINFO_USEMARK")));
        funcInfoVo.setFuncEdit(jsonAssist.yesOrNo2boolean(funcBean.getStr("FUNCINFO_USEEDIT")));

        //构建功能版本
        long lastVersion = System.currentTimeMillis();
        funcBean.set("FUNCINFO_ZHJTSJ", lastVersion);
        funcInfoVo.setLastVersion(String.valueOf(lastVersion));
//        metaService.executeSql("UPDATE JE_CORE_FUNCINFO SET FUNCINFO_ZHJTSJ='" + lastVersion + "' WHERE FUNCINFO_FUNCCODE='" + funcBean.getStr("FUNCINFO_FUNCCODE") + "'");
        return funcInfoVo;
    }

    private Map<String, Object> buildFuncConfigInfo(DynaBean funcBean, FuncInfo funcInfoVo, List<DynaBean> children) {
        //功能集合
        Map<String, Object> funcConfig = new HashMap<String, Object>();
        funcBean.set("FUNCINFO_HELPBTN", StringUtil.isEmpty(funcBean.getStr("FUNCINFO_HELP")) ? "0" : "1");
        funcBean.remove("FUNCINFO_HELP");
        //1.装载功能基本信息
        funcConfig.put("info", funcBean.getValues());
        //2.构建模型信息
        String tableName = funcBean.getStr("FUNCINFO_TABLENAME");
        //2.初始化功能-->类表项信息
        /**
         * 查找默认的列表方案
         */
        DynaBean planColumn = metaService.selectOne("JE_CORE_RESOURCECOLUMN_PLAN", ConditionsWrapper.builder()
                .eq("PLAN_DEFAULT", "1")
                .eq("SY_STATUS", "1")
                .eq("PLAN_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID")));
        String RESOURCECOLUMN_PLAN_ID = (planColumn == null ? "" : planColumn.getStr("RESOURCECOLUMN_PLAN_ID"));
        //多功能
        /*List<DynaBean> columns = metaService.select("JE_CORE_RESOURCECOLUMN", ConditionsWrapper.builder()
                .eq("RESOURCECOLUMN_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .eq("RESOURCECOLUMN_PLAN_ID",RESOURCECOLUMN_PLAN_ID)
                .orderByAsc("SY_ORDERINDEX"));*/

        List<DynaBean> columns = metaService.select("JE_CORE_RESOURCECOLUMN", ConditionsWrapper.builder()
                .eq("RESOURCECOLUMN_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .orderByAsc("SY_ORDERINDEX"));
        String funcType = funcBean.getStr("FUNCINFO_FUNCTYPE");

        List<Model> models;
        if ("procedure".equals(funcType) || "sql".equals(funcType) || "iditprocedure".equals(funcType)) {
            models = new ArrayList<Model>();
            for (DynaBean column : columns) {
                if ("1".equals(column.getStr("SY_FLAG"))) {
                    String code = column.getStr("RESOURCECOLUMN_CODE");
                    String columnType = column.getStr("RESOURCECOLUMN_SYSMODE");
                    Model model = new Model(code, columnType);
                    models.add(model);
                }
            }
            //添加SQL类型功能的SQL
            funcInfoVo.setSql(funcBean.getStr("FUNCINFO_SQL"));
        } else if (StringUtils.countMatches(tableName, ".") > 1) {
            Field[] fields = EntityUtils.getInstance().getEntityInfo(tableName).getAllBaseFields();
            models = jsonAssist.getMoldeListByFields4Extjs(tableName, fields, null);
        } else {
            DynaBean resourceTable = metaBeanService.getResourceTable(tableName);
            models = jsonAssist.getMoldeListByFields4Extjs(tableName, (List<DynaBean>) resourceTable.get(BeanService.KEY_TABLE_COLUMNS), null);
        }
        funcConfig.put("modelFields", models);

        //处理策略
        for (DynaBean column : columns) {
            //策略
            Set<FuncColumnTactic> tactics = new HashSet<>();
            //策略
            FuncColumnTactic tactic;
            //策略中核心配置项
            FuncColumnTacticInfo v;
            if (jsonAssist.yesOrNo2boolean(column.getStr("RESOURCECOLUMN_HIGHLIGHTING"))) {
                tactic = new FuncColumnTactic();
                tactic.setName("highlighting");
                v = new FuncColumnTacticInfo();
                //策略1颜色方案
                v.setColor(column.getStr("RESOURCECOLUMN_COLOR1"));
                //关键字段组建名称
                v.setKeyWord(column.getStr("RESOURCECOLUMN_KEYWORD"));
                //装载V
                tactic.setV(v);
                //装载策略
                tactics.add(tactic);
            }
            if (jsonAssist.yesOrNo2boolean(column.getStr("RESOURCECOLUMN_HYPERLINK"))) {
                tactic = new FuncColumnTactic();
                tactic.setName("hyperLink");
                v = new FuncColumnTacticInfo();
                // 连接方法
                v.setLinkMethod(column.getStr("RESOURCECOLUMN_LINKMETHOD"));
                //装载V
                tactic.setV(v);
                //装载策略
                tactics.add(tactic);
            }
            column.set("tactics", tactics);
        }
        funcConfig.put("columns", jsonBuilder.buildDynaValues(columns));

        //2.初始化功能-->表单信息
        /**
         * 查找默认的列表方案
         */
        DynaBean planFileld = metaService.selectOne("JE_CORE_RESOURCEFIELD_PLAN", ConditionsWrapper.builder()
                .eq("PLAN_DEFAULT", "1")
                .eq("SY_STATUS", "1")
                .eq("PLAN_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID")));
        String RESOURCEFIELD_PLAN_ID = (planFileld == null ? "" : planFileld.getStr("RESOURCEFIELD_PLAN_ID"));
        //多功能
        /*List<DynaBean> fields = metaService.select("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder()
                .eq("RESOURCEFIELD_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .eq("RESOURCEFIELD_PLAN_ID",RESOURCEFIELD_PLAN_ID)
                .orderByAsc("SY_ORDERINDEX"));*/

        List<DynaBean> fields = metaService.select("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder()
                .eq("RESOURCEFIELD_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .orderByAsc("SY_ORDERINDEX"));
        Map<String, String> fieldDefalutInfos = new HashMap<>();
        for (DynaBean field : fields) {
            String defaultVal = field.getStr("RESOURCEFIELD_VALUE", "");
            String fieldCode = field.getStr("RESOURCEFIELD_CODE");
            if (StringUtil.isNotEmpty(defaultVal)) {
                fieldDefalutInfos.put(fieldCode, defaultVal);
            }
        }
        funcConfig.put("fields", jsonBuilder.buildDynaValues(fields));

        //3.初始化功能-->按钮
        List<DynaBean> buttons = metaService.select("JE_CORE_RESOURCEBUTTON", ConditionsWrapper.builder()
                .eq("RESOURCEBUTTON_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .orderByAsc("SY_ORDERINDEX"));
        funcConfig.put("buttons", jsonBuilder.buildDynaValues(buttons));
        funcConfig.put("children", jsonBuilder.buildDynaValues(children));
        //6.工作流
//        List<ProcessInfo> wfProcess = new ArrayList<ProcessInfo>();
//        funcConfig.put("workflowInfo", wfProcess);
        //7.封装查询策略
        List<DynaBean> queryStrategys = metaService.select("JE_CORE_QUERYSTRATEGY", ConditionsWrapper.builder().eq("QUERYSTRATEGY_FUNCCODE", funcBean.getStr("FUNCINFO_FUNCCODE")));
        funcConfig.put("queryStrategys", jsonBuilder.buildDynaValues(queryStrategys));
        //8.公共高级查询
        List<DynaBean> groupQuerys = metaService.select("JE_CORE_GROUPQUERY", ConditionsWrapper.builder().eq("GROUPQUERY_GNID", funcBean.getStr("JE_CORE_FUNCINFO_ID")).orderByAsc("GROUPQUERY_PX"));
        funcConfig.put("groupQuerys", jsonBuilder.buildDynaValues(groupQuerys));
        //9.封装数据流转 暂时不启用
        List<DynaBean> dataflows = metaService.select("JE_CORE_DATAFLOW", ConditionsWrapper.builder()
                .eq("DATAFLOW_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .orderByAsc("SY_ORDERINDEX"));
        funcConfig.put("dataflows", jsonBuilder.buildDynaValues(dataflows));
        //10.拓展配置（日历/甘特图）
        List<DynaBean> funcConfigs = metaService.select("JE_CORE_FUNC_CONFIG", ConditionsWrapper.builder().eq("JE_CORE_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID")).orderByDesc("SY_CREATETIME"));
        funcConfig.put("funcConfigs", jsonBuilder.buildDynaValues(funcConfigs));
        funcConfig.put("lastVersion", funcInfoVo.getLastVersion());
        /**
         * 列表打印方案
         */
        funcConfig.put("columnPrintPlan", metaService.selectOne("JE_CORE_RESOURCECOLUMN_PRINT_PLAN", ConditionsWrapper.builder()
                .selectColumns("PLAN_PRINT_CONFIG,PLAN_DEFAULT")
                .eq("PLAN_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .eq("PLAN_DEFAULT", "1")));
        /**
         * 表单打印方案
         */
        funcConfig.put("fieldPrintPlan", metaService.selectOne("JE_CORE_RESOURCEFIELD_PRINT_PLAN", ConditionsWrapper.builder()
                .selectColumns("PLAN_PRINT_CONFIG,PLAN_DEFAULT")
                .eq("PLAN_FUNCINFO_ID", funcBean.getStr("JE_CORE_FUNCINFO_ID"))
                .eq("PLAN_DEFAULT", "1")));
        return funcConfig;
    }

    @Override
    public List<DynaBean> findFuncInfoDics(String funcIds) {
        List<DynaBean> fields = metaService.select("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder().apply(" AND RESOURCEFIELD_XTYPE IN ('rgroup','cgroup','cbbfield','treessfield','treessareafield','cbblistfield') AND RESOURCEFIELD_FUNCINFO_ID IN (SELECT JE_CORE_FUNCINFO_ID FROM JE_CORE_FUNCINFO WHERE FUNCINFO_FUNCCODE IN (" + StringUtil.buildArrayToString(funcIds.split(",")) + "))"));
        List<String> ddCodes = new ArrayList<String>();
        for (DynaBean field : fields) {
            String configInfo = field.getStr("RESOURCEFIELD_CONFIGINFO");
            if (StringUtil.isNotEmpty(configInfo)) {
                ddCodes.add(configInfo.split(ArrayUtils.SPLIT)[0]);
            }
        }
        List<DynaBean> dics = metaService.select("JE_CORE_DICTIONARY", ConditionsWrapper.builder().in("DICTIONARY_DDCODE", ddCodes).apply("and (SY_STATUS = '' or SY_STATUS = '1' or SY_STATUS is NULL)"));
        return dics;
    }

    @Override
    public Map<String, Object> getInformationById(String pkValue, String code, String type) {
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isNotEmpty(code)) {
            List<Map<String, Object>> listDB = metaService.selectSql("select f.*,r.JE_CORE_RESOURCETABLE_ID,r.RESOURCETABLE_IMPORT,r.RESOURCETABLE_TABLESINFO from (select * from JE_CORE_FUNCINFO where FUNCINFO_FUNCCODE={0}) f  LEFT JOIN je_core_resourcetable r on FUNCINFO_TABLENAME=RESOURCETABLE_TABLECODE", code);
            if (listDB != null && listDB.size() > 0) {
                map = listDB.get(0);
            }
        }

        if (StringUtils.isNotEmpty(pkValue)) {
            if (StringUtils.isNotEmpty(type)) {
                String field = FuncinfoEnum.valueOf(type).getValue();
                List<Map<String, Object>> listDB = metaService.selectSql("select f.*,r.JE_CORE_RESOURCETABLE_ID,r.RESOURCETABLE_COORDINATE,r.RESOURCETABLE_IMPORT,r.RESOURCETABLE_TABLESINFO from (select " + field + " from JE_CORE_FUNCINFO where JE_CORE_FUNCINFO_ID={0}) f  LEFT JOIN je_core_resourcetable r on FUNCINFO_TABLENAME=RESOURCETABLE_TABLECODE", pkValue);
                if (listDB != null && listDB.size() > 0) {
                    map = listDB.get(0);
                }
            } else {
                List<Map<String, Object>> listDB = metaService.selectSql("select f.*,r.JE_CORE_RESOURCETABLE_ID,r.RESOURCETABLE_IMPORT,r.RESOURCETABLE_TABLESINFO from (select * from JE_CORE_FUNCINFO where JE_CORE_FUNCINFO_ID={0}) f  LEFT JOIN je_core_resourcetable r on FUNCINFO_TABLENAME=RESOURCETABLE_TABLECODE", pkValue);
                if (listDB != null && listDB.size() > 0) {
                    map = listDB.get(0);
                }
            }
            JSONArray jsonArray = workFlowInfoRpcService.getWorkFlowInfoByFuncCode(map.get("FUNCINFO_FUNCCODE").toString());
            map.put("FUNCINFO_BINDING_WORKFLOW", getWorkflowInfo(jsonArray, "name"));
            map.put("FUNCINFO_BINDING_WORKFLOWID", getWorkflowInfo(jsonArray, "id"));
        }
        return map;
    }

    @Override
    public Map<String, String> getWorkflowByfuncCode(String code) {
        Map<String, String> map = new HashMap<>();
//        JSONArray jsonArray = workFlowInfoRpcService.getWorkFlowInfoByFuncCode(code);
//        map.put("FUNCINFO_BINDING_WORKFLOW",getWorkflowInfo(jsonArray,"name"));
//        map.put("FUNCINFO_BINDING_WORKFLOWID",getWorkflowInfo(jsonArray,"id"));
        return map;
    }

    @Override
    @Transactional
    public void doUpdateFuncCode(DynaBean dynaBean) {
        DynaBean funcInfo = metaService.selectOneByPk("JE_CORE_FUNCINFO", dynaBean.getStr("JE_CORE_FUNCINFO_ID"));
        //重新授权
        if ("FUNCFIELD".equals(funcInfo.getStr("FUNCINFO_NODEINFOTYPE")) || "FUNC".equals(funcInfo.getStr("FUNCINFO_NODEINFOTYPE"))) {
            permissionRpcService.transferFuncPermission(funcInfo.getStr("FUNCINFO_FUNCCODE"), dynaBean.getStr("FUNCINFO_FUNCCODE"));
        }
        //更新功能编码
        commonService.buildModelModifyInfo(dynaBean);
        metaService.update(dynaBean);
        //若关联菜单，则修改菜单配置信息
        List<DynaBean> list = metaRbacService.selectByTableCodeAndNativeQuery("JE_CORE_MENU", NativeQuery.build().eq("MENU_NODEINFO", funcInfo.getStr("FUNCINFO_FUNCCODE")));
        for (DynaBean menu : list) {
            menu.table("JE_CORE_MENU");
            menu.setStr("MENU_NODEINFO", dynaBean.getStr("FUNCINFO_FUNCCODE"));
            metaRbacService.updateByNatieQuery(menu, NativeQuery.build().eq("JE_CORE_MENU_ID", menu.getStr("JE_CORE_MENU_ID")));
        }
        //若有数据权限，则修改数据权限的功能code
        List<DynaBean> funcPermList = metaService.select("JE_CORE_FUNCPERM", ConditionsWrapper.builder().eq("FUNCPERM_FUNCINFO_CODE", funcInfo.getStr("FUNCINFO_FUNCCODE")));
        if (funcPermList != null && funcPermList.size() > 0) {
            metaService.executeSql("UPDATE JE_CORE_FUNCPERM SET FUNCPERM_FUNCINFO_CODE='" + dynaBean.getStr("FUNCINFO_FUNCCODE") + "' WHERE FUNCPERM_FUNCINFO_CODE='" + funcInfo.getStr("FUNCINFO_FUNCCODE") + "'");
        }
    }

    @Override
    public void checkFuncUseWf(String tableName, String productCode, String resourceTableId) {
        List<DynaBean> dynaBeanList = metaService.select("JE_CORE_TABLECOLUMN", ConditionsWrapper.builder().eq("TABLECOLUMN_RESOURCETABLE_ID", resourceTableId));
        boolean haveWfField = false;
        //看有没有流程相关的字段
        if (dynaBeanList != null && dynaBeanList.size() > 0) {
            for (DynaBean dynaBean : dynaBeanList) {
                String tableColumnCode = dynaBean.getStr("TABLECOLUMN_CODE");
                if (!Strings.isNullOrEmpty(tableColumnCode) && "SY_PREAPPROVUSERS".equals(tableColumnCode)) {
                    haveWfField = true;
                    break;
                }
            }
        }
        if (!haveWfField) {
            DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceTableId);
            if (table != null) {
                boolean status;
                try {
                    //添加流程辅助相关字段
                    status = metaTableColumnService.initProcessExtendColumns(table);
                } catch (APIWarnException e) {
                    throw new PlatformException(e.getMessage(), PlatformExceptionEnum.UNKOWN_ERROR);
                }
                if (!status) {
                    throw new PlatformException("流程相关字段添加失败！", PlatformExceptionEnum.UNKOWN_ERROR);
                }
                //检查表是否创建
                String result = DataBaseUtils.checkTableExists(table.getStr("RESOURCETABLE_TABLECODE"));
                if ("1".equals(table.getStr("RESOURCETABLE_ISCREATE")) && !"0".equals(result)) {
                    //修改表，功能列表，信息 ？ 根据不同产品CODE 调不同服务
                    boolean updateStatus = updateTable(productCode, resourceTableId);
                    if (!updateStatus) {
                        throw new PlatformException("流程相关字段添加失败！", PlatformExceptionEnum.UNKOWN_ERROR);
                    }
                }
//                //清除对应缓存
                tableCache.removeCache(tableName);
                dynaCache.removeCache(tableName);
            } else {
                throw new PlatformException("功能对应表信息不存在！", PlatformExceptionEnum.UNKOWN_ERROR);
            }
        }
    }

    @Override
    public DynaBean copyFunc(String newFuncName, String newFuncCode, String parentId, DynaBean oldFuncInfo) {
        DynaBean newFunc = oldFuncInfo.clone();

        DynaBean parentFuncInfo = metaService.selectOneByPk("JE_CORE_FUNCINFO", parentId);

        String funcId = JEUUID.uuid();
        newFunc.set("JE_CORE_FUNCINFO_ID", funcId);
        newFunc.set("SY_PATH", parentFuncInfo.getStr("SY_PATH") + "/" + funcId);
        newFunc.set("SY_PARENT", parentId);
        newFunc.set("SY_LAYER", Integer.parseInt(parentFuncInfo.getStr("SY_LAYER")) + 1);
        newFunc.set("FUNCINFO_FUNCCODE", newFuncCode);
        newFunc.set("FUNCINFO_FUNCNAME", newFuncName);
        newFunc.set("SY_PARENTPATH", parentFuncInfo.getStr("SY_PATH"));
        //不启用工作流，因为工作流是复制不过来
        newFunc.set("FUNCINFO_USEWF", "0");
        commonService.buildModelCreateInfo(newFunc);
        commonService.generateTreeOrderIndex(newFunc);
        metaService.insert(newFunc);
        //增加子表数据
        String oldFuncId = oldFuncInfo.getStr("JE_CORE_FUNCINFO_ID");
        metaCopyFuncService.copyButton(funcId, oldFuncId);
        metaCopyFuncService.copyColumn(funcId, oldFuncId);
        metaCopyFuncService.copyDataFlow(funcId, oldFuncId);
        metaCopyFuncService.copyField(funcId, oldFuncId);
        metaCopyFuncService.copyQuerys(funcId, oldFuncId);
        metaCopyFuncService.copyStrategies(funcId, newFuncCode, oldFuncId);
        return newFunc;
    }

    /**
     * 子功能配置：
     * 如果FUNCRELATION_TABLENAME配置的是字段，这个会区分大小写
     * 如果FUNCRELATION_TABLENAME配置的是接口地址，必须保证接口地址唯一性
     * 还需要增加一个参数config，是url的参数
     *
     * @param funcRelationId
     * @param dataId
     * @param funcCode
     * @return
     */
    @Override
    public JSONTreeNode getFileInfoList(String funcRelationId, String dataId, String funcCode) {

        DynaBean funcRelation = metaService.selectOneByPk("JE_CORE_FUNCRELATION", funcRelationId);
        if (!"file".equals(funcRelation.getStr("FUNCRELATION_RELYONTYPE"))) {
            return new JSONTreeNode();
        }

        if (StringUtil.isEmpty(funcRelation.getStr("FUNCRELATION_TABLENAME"))) {
            return new JSONTreeNode();
        }
        String[] codeArr = funcRelation.getStr("FUNCRELATION_TABLENAME").split(",");

        DynaBean funcInfo = metaService.selectOne("JE_CORE_FUNCINFO",
                ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", funcCode));

        String tableCode = funcInfo.getStr("FUNCINFO_TABLENAME");
        String productCode = funcInfo.getStr("SY_PRODUCT_CODE");

        DynaBean data = getDataList(productCode, tableCode, dataId);

        List<DynaBean> list = metaService.select("JE_CORE_TABLECOLUMN",
                ConditionsWrapper.builder().in("TABLECOLUMN_CODE", Arrays.asList(codeArr))
                        .eq("TABLECOLUMN_TABLECODE", tableCode));
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        Map<String, Object> map = data.getValues();
        for (DynaBean column : list) {
            String code = column.getStr("TABLECOLUMN_CODE");
            if (map.containsKey(code) && StringUtil.isNotEmpty(map.get(code))) {
                JSONTreeNode codeTree = buildCodeTree(rootNode.getId(), column);
                String files = map.get(code).toString();
                JSONArray jsonArray = JSON.parseArray(files);
                codeTree.getChildren().addAll(getFileInfoTreeChild(codeTree.getId(), jsonArray));
                rootNode.getChildren().add(codeTree);
            }
        }
        return rootNode;
    }

    private DynaBean getDataList(String productCode, String tableCode, String dataId) {
        if (PRODUCT_CORE_META.equals(productCode)) {
            return metaService.selectOneByPk(tableCode, dataId);
        } else {
            CommonTableRpcService commonTableRpcService = RpcSchemaFactory.getRemoteProvierClazz(productCode,
                    "commonTableRpcService", CommonTableRpcService.class);
            return commonTableRpcService.selectOneByPk(tableCode, dataId);
        }
    }

    private List<JSONTreeNode> getFileInfoTreeChild(String parentId, JSONArray jsonArray) {
        List<JSONTreeNode> list = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            JSONTreeNode node = new JSONTreeNode();
            node.setId(jsonObject.getString("fileKey"));
            node.setParent(parentId);
            node.setLeaf(true);
            node.setText(jsonObject.getString("relName"));
            node.setNodeType("LEAF");
            node.setNodeInfoType(jsonObject.getString("suffix"));
            list.add(node);
        }
        return list;
    }

    private JSONTreeNode buildCodeTree(String parentId, DynaBean column) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(column.getPkValue());
        node.setParent(parentId);
        node.setLeaf(true);
        node.setText(column.getStr("TABLECOLUMN_NAME"));
        node.setCode(column.getStr("TABLECOLUMN_CODE"));
        node.setOrderIndex(column.getStr("SY_ORDERINDEX"));
        node.setNodeInfo(column.getStr("TABLECOLUMN_CODE"));
        node.setNodeType("GENERAL");
        //node.setNodePath(dataSource.getStr("SY_PATH"));
        //node.setDescription(dataSource.getStr("DATASOURCE_REMARK"));
        //node.setNodeInfoType("DataSource");
        return node;
    }

    public boolean updateTable(String productCode, String resourceTableId) {
        if (PRODUCT_CORE_META.equals(productCode)) {
            return tableService.updateTable(resourceTableId, true);
        } else {
            UpdateFuncTableInvokeRpcService metaTableRpcService = RpcSchemaFactory.getRemoteProvierClazz(productCode,
                    "updateFuncTableInvokeRpcService", UpdateFuncTableInvokeRpcService.class);
            return metaTableRpcService.invoke("metaTableRpcService", "updateFunTable", resourceTableId);
        }
    }

    private String getWorkflowInfo(JSONArray jsonArray, String type) {
        if (jsonArray != null && jsonArray.size() > 0) {
            List<String> names = new ArrayList<>();
            List<String> ids = new ArrayList<>();
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String name = jsonObject.getString("name");
                names.add(name);
                String id = jsonObject.getString("id");
                ids.add(id);
            }
            if ("name".equals(type)) {
                return org.apache.commons.lang.StringUtils.join(names, ",");
            }
            if ("id".equals(type)) {
                return org.apache.commons.lang.StringUtils.join(ids, ",");
            }
        }
        return null;
    }

}
